"Fossies" - the Fresh Open Source Software Archive

Member "eric6-20.8/eric/docs/eric6-plugin.odt" (4 May 2019, 545966 Bytes) of package /linux/misc/eric6-20.8.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format (assuming odt format). Alternatively you can here view or download the uninterpreted source code file. A member file download can also be achieved by clicking within a package contents listing on the according byte size field.

The eric6 plug-in system

Version 18.02

Copyright © 2007-2018 Detlev Offenbach <detlev@die-offenbachs.de>

Introduction

eric 4.1 introduced a plug-in system, which allows easy extension of the IDE. Every user can customize the application by installing plug-ins available via the Internet. This document describes this plug-in system from a user perspective and from a plug-in developers perspective as well.

Description of the plug-in system

The eric6 plug-in system is the extensible part of the eric6 IDE. There are two kinds of plug-ins. The first kind of plug-ins are automatically activated at startup, the other kind are activated on demand. The activation of the on-demand plug-ins is controlled by configuration options. Internally, all plug-ins are managed by the PluginManager object. Deactivated autoactivate plug-ins are remembered and will not be activated automatically on the next start of eric6.

Eric6 comes with quite a number of core plug-ins. These are part of the eric6 installation. In addition to this, there are additional plug-ins available via the internet. Those plug-ins may be installed and uninstalled using the provided menu or toolbar entries. Installable plug-ins live in one of two areas. One is the global plug-in area, the other is the user plug-in area. The later one overrides the global area.

The plug-in system from a user perspective

The eric6 plug-in system provides the user with a Plug-ins menu in the main menu bar and a corresponding toolbar. Through both of them the user is presented with actions to show information about loaded plug-ins and to install or uninstall plug-ins.

The Plug-ins menu and toolbar

The plug-ins menu is located under the “Plugins” label in the main menu bar of the eric6 main window. It contains all available user actions and is accompanied by a toolbar containing the same actions. They are shown in the following figures.

Figure 1: eric6 main menu
Figure 2: The Plug-ins menu
Figure 3: The Plug-ins toolbar

The “Plugin Infos...” action is used to show a dialog, that lists all the loaded plug-ins and there status. The entry labeled “Install Plugins...” opens a wizard like dialog to install new plug-ins from plug-in archives. The entry, “Uninstall Plugin...”, presents a dialog to uninstall a plug-in. If a plug-in to be uninstalled is loaded, it is unloaded first. The entry called “Plugin Repository...” shows a dialog, that displays the official plug-ins available in the eric6 plug-in repository. The “Configure...” entry opens the eric6 configuration dialog displaying the Plugin Manager configuration page.

The Plug-in Infos dialog

The “Plugin Infos” dialog shows information about all loaded plug-ins. Plug-ins, which had a problem when loaded or activated are highlighted. More details are presented, by double clicking an entry or selecting the “Show details” context menu entry. An example of the dialog is show in the following figure.

Figure 4: Plug-ins Info dialog

The columns show information as follows.

This dialog has a context menu, which has entries to show more details about a selected plug-in and to activate or deactivate an autoactivate plug-in. It is shown below.

Figure 5: Plug-ins Info dialog context menu

Deactivated plug-ins are remembered and will not be activated automatically at the next startup of eric6. In order to reactivate them, the “Activate” entry of the context menu must be selected.

Selecting the “Show details” entry opens another dialog with more information about the selected plug-in. An example is shown in the following figure.

Figure 6: Plug-in Details dialog

The entries of the dialog are as follows.

Installing Plug-ins

New plug-ins are installed from within eric6 using the Plug-in Installation dialog. It is show, when the “Install Plugin...” menu entry is selected. Please note, that this is also available as a standalone tool using the eric6_plugininstall.py script or via the eric6 tray menu. The user is guided through the installation process by a wizard like dialog. On the first page, the plug-in archives are selected. eric6 plug-ins are distributed as ZIP-archives, which contain all installable files. The “Add ...”-button opens a standard file selection dialog. Selected archives may be removed from the list with the “Remove”-Button. Pressing the “Next >” button continues to the second screen.

Figure 7: Plug-ins Installation dialog, step 1

The second display of the dialog is used to select the directory, the plug-in should be installed into. If the user has write access to the global eric6 plug-ins directory, both the global and the user plug-ins directory are presented. Otherwise just the user plug-ins directory is given as a choice. With the “< Back” button, the user may go back one screen. Pressing “Next >” moves to the final display.

Figure 8: Plug-ins Installation dialog, step 2

The final display of the plug-in installation dialog shows a summary of the installation data entered previously. Again, the “< Back” button lets the user go back one screen. The “Finish” button is used to acknowledge the data and starts the installation process.

Figure 9: Plug-ins Installation dialog, step 3

The installation progress is show on the very same page. During installation the plug-in archives is checked for various conditions. If the installer recognizes a problem, a message is shown and the installation for this plug-in archive is aborted. If there is a problem in the last step, which is the extraction of the archive, the installation process is rolled back. The installation progress of each plug-in archive is shown by the progress bar.

Figure 10: Plug-ins Installation dialog, step 4

Once the installation succeeds, a success message is shown.

Figure 11: Plug-ins Installation dialog, step 5

If plug-ins are installed from within eric6 and are of type “autoactivate”, they are loaded and activated immediately. Otherwise they are loaded in order to add new on-demand functionality.

Uninstalling Plug-ins

Plug-ins may be uninstalled from within eric6 using the “Uninstall Plugin...” menu, via the eric6_pluginuninstall.py script or via the eric6 tray menu. This displays the “Plugin Uninstallation” dialog, which contains two selection list. The top list is used to select the plug-in directory. If the user has write access in the global plug-ins directory, the global and user plug-ins directory are presented. If not, only the user plug-ins directory may be selected. The second list shows the plug-ins installed in the selected plug-ins directory. Pressing the “OK” button starts the uninstallation process.

Figure 13: Plug-in Uninstallation dialog, step 2

The uninstallation process deactivates and unloads the plug-in and finally removes all files belonging to the selected plug-in from disk. This process ends with a message confirming successful uninstallation of the plug-in.

The Plug-ins repository

eric6 has a repository, that contains all official plug-ins. The plug-in repository dialog may be used to show this list and download selected plug-ins.

Figure 14: Plug-in Repository dialog

The upper part of the dialog shows a list of available plug-ins. This info is read from a file stored in the eric6 user space. Using the Update button, this file can be updated via the Internet. The plug-ins are grouped by their development status. An icon next to the version entry indicates, whether this plug-in needs an update. More detailed data is shown in the bottom part, when an entry is selected. The data shown is the URL of the plug-in, some detailed description and the author of the plug-in. Pressing the Download button gets the selected plug-ins from the presented URL and stores them in the user's plug-in download area, which may be configured on the Plug-ins configuration page of the configuration dialog. The Cancel button will interrupt the current download. The download progress is shown by the progress bar. Pressing the Close & Install button will close this dialog and open the plug-in installation dialog (s. chapter 3.3) The Download & Install button download the selected plug-ins, closes the dialog and opens the plug-in installation dialog. The Repository URL entry shows the location the repository data is downloaded from. By pressing the Edit URL button, this location might be changed by the user in case the location changes and the changed location could not be updated remotely.

Eric6 for plug-in developers

This chapter contains a description of functions, that support plug-in development with eric6. Eric6 plug-in projects must have the project type “Eric6 Plugin”. The project's main script must be the plug-in main module. These project entries activate the built-in plug-in development support. These are functions for the creation of plug-in archives and special debugging support. An example of the project properties is shown in the following figure.

Figure 15: Plug-in specific project properties

To support the creation of plug-in package archives, the Packagers submenu of the Project menu contains entries to ease the creation of a package list and to create the plug-in archive.

Figure 16: Packagers submenu

The “Create package list” entry creates a file called PKGLIST, which is used by the archive creator to get the list of files to be included in the plug-in archive. After the PKGLIST file has been created, it is automatically loaded into a new editor. The plug-in author should modify this list and shorten it to just include the files required by the plug-in at runtime. The following listing gives an example.

The PKGLIST file must be stored in the top level directory of the project alongside the project file.

The archive creator invoked via the “Create Plugin Archive” menu entry reads this package list file and creates a plug-in archive. This archive has the same name as the plug-in module and is stored at the same place. The menu entry “Create Plugin Archive (Snapshot)” is used to create a snapshot release of the plug-in. This command modifies the version entry of the plug-in module (see below) by appending a snapshot indicator consisting of “-snapshot-” followed by the date like “20141224”.

In order to debug a plug-in under development, eric6 has the command line switch
--plugin=<plugin module filename>”. That switch is used internally, if the project is of type “Eric6 Plugin”.

Anatomy of a plug-in

This chapter describes the anatomy of a plug-in in order to be compatible with eric6.

Plug-in structure

An eric6 plug-in consists of the plug-in module file and optionally of one plug-in package directory. The plug-in module file must have a filename, that starts with Plugin and ends with .py, e.g. PluginRefactoringBRM.py. The plug-in package directory may have an arbitrary name, but must be unique upon installation. Therefore it is recommended to give it the name of the module without the Plugin prefix. This package directory name must be assigned to the packageName module attribute (see the chapter describing the plug-in module header).

Plug-in header

The plug-in module must contain a plug-in header, which defines various module attributes. An example is given in the listing below.

The various attributes to be defined in the header are as follows.

If the autoactivate attribute is False, the header must contain two additional attributes.

Plug-in modules may define additional optional attributes. Optional attributes recognized by eric6 are as follows.

If either the version or the className attribute is missing, the plug-in will not be loaded. If the autoactivate attribute is missing or this attribute is False and the pluginType or the pluginTypename attributes are missing, the plug-in will be loaded but not activated. If the packageName attribute is missing, the plug-in installation will be refused by eric6.

Plug-in module functions

Plug-in modules may define the following module level functions recognized by the eric6 plug-in manager.

These functions are described in more detail in the next few chapters.

moduleSetup()

This function may be defined for on-demand plug-ins (i.e. those with autoactivate being False). It may be used to perform some module level setup. E.g. the CVS plug-in uses this function, to instantiate an administrative object to provide the login and logout menu entries of the version control submenu.

prepareUninstall()

This function is called by the plug-in uninstaller just prior to uninstallation of the plug-in. That is the right place for cleanup code, which removes entries in the settings object or removes plug-in specific configuration files.

getConfigData()

This function may be used to provide data needed by the configuration dialog to show an entry in the list of configuration pages and the page itself. It is called for active autoactivate plug-ins. It must return a dictionary with globally unique keys (e.g. created using the plug-in name) and lists of five entries. These are as follows.

previewPix()

This function may be used to provide a preview pixmap of the plug-in. This is just called for viewmanager plug-ins (i.e. pluginType == "viewmanager"). The returned object must be of type QPixmap.

exeDisplayData()

This function may be defined by modules, that depend on some external tools. It is used by the External Programs info dialog to get the data to be shown. This function must return a dictionary that contains the data for the determination of the data to be shown or a dictionary containing the data to be shown.

The required entries of the dictionary of type 1 are described below.

The required entries of the dictionary of type 2 are described below.

exeDisplayDataList()

In case the plugin has to report more than one external tool, it can define the function exeDisplayDataList in its module. The returned list has to consist of exeDisplayData type 1 or type 2 dictionaries (see 5.3.5 exeDisplayData()).

apiFiles(language)

This function may be provided by plug-ins providing API files for the autocompletion and calltips system of eric6. The function must accept the programming language as a string and return the filenames of the provided API files for that language as a list of string.

clearPrivateData()

This function may be provided by plug-ins defining private data in order to clear them upon requested by the user.

Plug-in object methods

The plug-in class as defined by the className attribute must implement three mandatory methods.

These functions are described in more detail in the next few chapters.

__init__(self, ui)

This method is the constructor of the plug-in object. It is passed a reference to the main window object, which is of type UI.UserInterface. The constructor should be used to perform all initialization steps, that are required before the activation of the plug-in object. E.g. this would be the right place to load a translation file for the plug-in (s. ) and to initialize default values for preferences values.

activate(self)

This method is called by the plug-in manager to activate the plug-in object. It must return a tuple giving a reference to the object implementing the plug-in logic (for on-demand plug-ins) or None and a flag indicating the activation status. This method should contain all the logic, that is needed to get the plug-in fully operational (e.g. connect to some signals provided by eric6). If the plug-in wants to provide an action to be added to a toolbar, this action should be registered with the toolbar manager instead of being added to a toolbar directly.

deactivate(self)

This method is called by the plug-in manager to deactivate the plug-in object. It is called for modules, that have the deactivateable module attribute set to True. This method should disconnect all connections made in the activate method and remove all menu entries added in the activate method or somewhere else. If the cleanup operations are not done carefully, it might lead to crashes at runtime, e.g. when the user invokes an action, that is no longer available. If the plug-in registered an action with the toolbar manager, this action must be unregistered.

__loadTranslator(self)

The constructor example shown in loads a plug-in specific translation using this method. The way, how to do this correctly, is shown in the following listing. It is important to keep a reference to the loaded QTranslator object. Otherwise, the Python garbage collector will remove this object, when the method is finished.

initToolbar(self, ui, toolbarManager)

This method must be implemented, if the plug-in supports a toolbar for its actions. Such toolbar will be removed, when the plug-in is unloaded. An example is shown in .

prepareUnload(self)

This method must be implemented to prepare the plug-in to be unloaded. It should revert everything done when the plug-in was instantiated and remove plug-in toolbars generated with initToolbar(). shows an example.

Eric6 hooks

This chapter describes the various hooks provided by eric6 objects. These hooks may be used by plug-ins to provide specific functionality instead of the standard one.

Hooks of the project browser objects

Most project browser objects (i.e. the different tabs of the project viewer) support hooks. They provide methods to add and remove hooks.

Hooks of the ProjectFormsBrowser object

The ProjectFormsBrowser object supports hooks with these keys.

Hooks of the ProjectResourcesBrowser object

The ProjectResourcesBrowser object supports hooks with these keys.

Hooks of the ProjectTranslationsBrowser object

The ProjectTranslationsBrowser object supports hooks with these keys.

Hooks of the Editor object

The Editor object provides hooks for auto-completion and call-tips. These are the methods provided to register, remove and get these hooks and to return completion results.

Hooks of the CodeDocumentationViewer object

The CodeDocumentationViewer object provides hooks for documentation providers. These are the methods provided to register and unregister a provider and to return the requested documentation.

All these keys are optional.

Eric6 functions available for plug-in development

This chapter describes some functionality, that is provided by eric6 and may be of some value for plug-in development. For a complete eric6 API description please see the documentation, that is delivered as part of eric6.

The eric6 object registry

Eric6 contains an object registry, that can be used to get references to some of eric6's building blocks. Objects available through the registry are

Eric6's object registry is used as shown in this example.

The object registry provides these methods.

The action registries

Actions of type E5Action may be registered and unregistered with the Project or the UserInterface object. In order for this, these objects provide the methods

The getMenu() methods

In order to add actions to menus, the main eric6 objects Project, Editor and UserInterface provide the method getMenu(menuName). This method returns a reference to the requested menu or None, if no such menu is available. menuName is the name of the menu as a Python string. Valid menu names are:

Methods of the PluginManager object

The PluginManager object provides some methods, that might be interesting for plug-in development.

Methods of the UserInterface object

The UserInterface object provides some methods, that might be interesting for plug-in development.

Methods of the E5ToolBarManager object

The E5ToolBarManager object provides methods to add and remove actions and toolbars. These actions and toolbars are used to build up the toolbars shown to the user. The user may configure the toolbars using a dialog. The list of available actions are those, managed by the toolbar manager.

Methods of the Project object

The Project object provides methods to store and retrieve data to and from the project data store. This data store is saved in the project file.

The key parameter gives the key of the data entry to get and is determined by the plug-in. A copy of the requested data is returned.

The key parameter gives the key of the data entry to get and is determined by the plug-in. data is the data to store. The data is copied to the data store by using the Python function copy.deepcopy().

In addition to this the Project object contains methods to register and unregister additional project types.

Methods of the ProjectBrowser object

The ProjectBrowser object provides some methods, that might be interesting for plug-in development.

Methods of QScintilla.Lexer

The QScintilla.Lexer package provides methods to register and unregister lexers (syntax highlighters) provided by a plugin.

Signals

This chapter lists some Python type signals emitted by various eric6 objects, that may be interesting for plug-in development.

Special plug-in types

This chapter describes some plug-ins, that have special requirements.

VCS plug-ins

VCS plug-ins are loaded on-demand depending on the selected VCS system for the current project. VCS plug-ins must define their type by defining the module attribute pluginType like

pluginType = "version_control"

VCS plug-ins must implement the getVcsSystemIndicator() module function. This function must return a dictionary with the indicator as the key as a Python string and a tuple of the VCS name (Python string) and the VCS display string (string) as the value. An example is shown below.

ViewManager plug-ins

ViewManager plug-ins are loaded on-demand depending on the selected view manager. The view manager type to be used may be configured by the user through the configuration dialog. ViewManager plug-ins must define their type by defining the module attribute pluginType like

pluginType = "viewmanager"

The plug-in module must implement the previewPix() method as described above.

The BackgroudService

Introduced with Eric 5.5, the background service becomes part of the core system. It's a kind of remote procedure call, but other than, e.g. XMLRPC or CORBA, it's non blocking. Mainly developed to simplify the problems with some core modules, where the execution depends on the different Python versions, it could be used by other plug-ins as well. Even other languages than Python could be attached to the server side of the background service, to enhance Eric 5.

On the start of Eric, typically the Python 2 and 3 interpreters are started with Eric and some core plug-ins use them. Which interpreter is started, depends on the interpreter given in Settings → Debugger.

Based on the BackgroudService there are some core plug-ins which use it already to do their tasks.

How to access the background service

The interface, the background service supports, is quite simple. First of all, a plug-in has to get access to it through the object registry (refer to 7.1The eric6 object registry“).

Now it has access to the background service interface (the server side) and can announce its functions. Therefore the method serviceConnect must be called. To keep the background service universal, a plug-in has to specify, e.g. the callback function which itself can emit a self defined signal.

The signature is

serviceConnect(fx, lang, modulepath, module, callback, onErrorCallback=None)

with

Each plug-in which is based on Python has to support a special function initService. The initService function has to return the main service function pointer and has to initialize everything that is needed by the plug-in main function, e.g. create the object if it's a class method instead of a simple function.

After a successful serviceConnect, the plug-in can request a remote procedure call through the enqueueRequest method provided by the background service. The plug-in therefore has to use the registered service name. Furthermore it has to provide the language to use and an identifier. This identifier can be used to match the enqueueRequest call with the corresponding callback. Typically the file name is used, but other basic data types like integer or float could be used. The last parameter contains a list of function arguments, which are transferred to the remote procedure. Any basic data type can be used as arguments, but tuples are converted to lists by the underlying JSON module.

The signature is

enqueueRequest(fx, lang, fn, data)

with

As the method name implies, the call of enqueueRequest only enqueues the request. If other requests are pending, the processing waits until it's his turn. In the current implementation this is also true if the language to use isn't busy. Future plug-ins should therefore be cooperative and wait for the response instead of enqueueing all their tasks. To avoid an overflow, only the arguments of a pending task are updated. This is the case if the service name, the language and the identifier are all the same on a new enqueueRequest call. But the position in the queue isn't changed.

On unload of a plug-in, it can remove the connection to the background service by calling serviceDisconnect.

The signature is

serviceDisconnect(fx, lang)

with

The SyntaxCheckService

Based on the background service, another general service was introduced. With the syntax check service, other languages than Python can implement a syntax check and reuse the dialogs and recurring checks for open files. Therefore a special interface is created to include the new language to the existing checking mechanism.

Like the background service, the SyntaxCheckService is also added to the Eric 5 object registry (see SyntaxCheckService).

A new language has to register itself to the syntax checker by calling addLanguage. Additionally the new language has to implement the client side of the syntax checker. One way is to use the existing client side implemented in Python to call the checker. But this is very slow because of the overhead which comes from starting the syntax checker over and over again. It's better, to implement a new client side in the programming language the checker finally is. A good starting point for this is to look in Utilities/BackgroundClient.py.

addLanguage takes some parameters to handle the new programming language. The example shows the call from PluginSyntaxChecker.py

The signature is

addLanguage(lang, env, path, module, getArgs, getExt, callback, onError)

with

path and module are the same as in the background service serviceConnect method. Depending on the import mechanisms of the language and the client implementation it may be not necessary to provide path and / or module. In this case just empty strings should be enough.

The problems reported back to the callback method are stored in a dictionary which can hold two keys: error and warnings. The values of those keys are similar: the error key holds only the first five arguments and is a one dimensional list. The warnings key holds a two dimensional list (list of lists) and uses all arguments. The arguments and their sequence in the list are as follows:

It's also possible to deactivate a language by calling removeLanguage with the name of the language.

To query which languages are already registered, a plug-in can call getLanguages to get a list with the names of the registered languages.

To filter out the unsupported files, a plug-in can check for a correct file extension by retrieving the registered extensions with a call of getExtensions. It returns a list of supported file extensions.

At last a plug-in could start a check for a file by itself, by calling syntaxCheck. The signature is

syntaxCheck(lang, filename, source="")

with