Plugins

Plugins are the primary way to extend XYZCommander functionality. In fact even base functionality is implemented mainly via plugins.

Plugins are being held in one of the following directories:

  • System plugins: subdirectory of main XYZCommander installation path (usually /usr/local/share/xyzcmd/plugins). All base system plugins are held here.
  • User plugins: Any other third-party plugins are held in ~/.xyzcmd/plugins.

In these directories namespace subdirectories are created (see below for more details).

Plugin entry-point is a main.py file inside plugin directory. This file should contain class named XYZPlugin sublclassed from libxyz.core.plugins.BasePlugin class.

XYZPlugin class should define following mandatory attributes:

NAME
Plugin name.
AUTHOR
Plugin author name. Preferably in format Name <foo@bar>.
VERSION
Plugin version.
BRIEF_DESCRIPTION
Brief one-line plugin description.
FULL_DESCRIPTION
Full plugin description. Put anything here.
NAMESPACE
Plugin namespace. See Namespaces

Also some optional attributes can be defined:

MIN_XYZ_VERSION
Minimal XYZCommander version the plugin can be used with. If none defined, plugin will be available to use with any XYZCommander version.
DOC
Plugin documentation. Usually configuration variables described here.
HOMEPAGE
Plugin home-page

Namespaces

Namespaces are used to hierarchically organize exported methods and to prevent method-names collisions.

Typical plugin namespace path is:

:<namespace>:<plugin-name>

Here <namespace> is one of the available namespaces:

- sys     - Virtual system plugins
- core    - Core plugins
- ui      - User-interface related
- vfs     - Virtual file-system related
- fsrules - FSRules extensions
- misc    - Other miscellaneous

Managment

All plugin management is performed using PluginManger instance, accessible as pm attribute of libxyz.core.XYZData object named xyz.

PluginManger supports following methods:

load(<plugin>)
Search for <plugin>, load it, instantiate, prepare (run prepare()) and return
reload(<plugin>)
Force [re]loading <plugin> even if it is already stored in cache.
from_load(<plugin>, <method>)
Load public method <method> from <plugin>.
from_load_data(<plugin>, <obj>)
Load public data <obj> from <plugin>.

In all cases <plugin> is a plugin namespace path.

Once loaded plugin is stored in cache, so subsequent calls will simply return it from cache. If reloading needed reload method is used.

Lifecycle

Only enabled plugins can be loaded and used. List of enabled plugins must be defined in Configuration files. Plugins are usually loaded by first request.

After plugin gets loaded for first time following actions take place:

  • An instance of XYZPlugin class created
  • A prepare() method is run

Plugin can export methods and data.

Plugin exports its public methods via ‘public’ dictionary of BasePlugin class. Access to public methods can be performed as:

  • plugin.public["method"]()
  • plugin.method()

Second variant is simpler, cleaner and therefore preferable.

Plugin exports its public data via ‘public_data’ dictionary of BasePlugin class. Access to public data can be performed as:

  • plugin.public_data["obj"]
  • plugin["obj"]

So, in general, access to public methods is performed as attribute access: plugin.method(), and access to public data is performed as dict-item access: plugin["data_obj"].

Following is an example of typical plugin usage in python code (other cases will be described later):

# Load plugin
hello = self.xyz.pm.load(":misc:hello")

# Call public method say_hello() directly
hello.say_hello()

# Access public data `some_object`
print hello["some_object"]

# Or load only the method itself using from_load
say_hello = self.xyz.pm.from_load(":misc:hello", "say_hello")

# And then call
say_hello()

# Load only the data object itself using from_load_data
some_object = self.xyz.pm.from_load_data(":misc:hello", "some_object")

Also see the Configuration files for how to bind plugin methods to keyboard shortcuts.

Configuration

Plugins configuration is performed using plugin_conf() function.

plugin_conf() is just a shorthand for let(plugin, opts, sect=”plugins”), so both methods can be used.

For example, if we’d have following block in plugins config:

plugin_conf(":misc:hello", {
   "show_version": true
})

Plugin :misc:hello can access show_version variable as:

show_version = self.conf[u"show_version"]

or:

show_version = xyz.conf[u"plugins"][u":misc:hello"][u"show_version"]

Virtual plugins

TODO

Table Of Contents

Previous topic

Skins

Next topic

Standard plugins

This Page