xonsh/docs/tutorial_xontrib.rst

180 lines
6.4 KiB
ReStructuredText
Raw Normal View History

2016-05-11 01:55:53 -04:00
.. _tutorial_xontrib:
************************************
Tutorial: Extensions (Xontribs)
2016-05-11 01:55:53 -04:00
************************************
Take a deep breath and prepare for some serious Show & Tell; it's time to
2016-05-11 03:48:16 -04:00
learn about xonsh extensions!
2016-05-11 01:55:53 -04:00
2022-05-05 00:32:20 +05:30
Xonsh comes with some default set of extensions. These can be viewed :py:mod:`here <xontrib>`.
Also checkout the list of `Awesome Contributions <https://xonsh.github.io/awesome-xontribs/>`_
from the community.
2016-05-11 01:55:53 -04:00
Overview
2022-05-05 00:32:20 +05:30
========
2016-05-11 01:55:53 -04:00
Xontributions, or ``xontribs``, are a set of tools and conventions for
extending the functionality of xonsh beyond what is provided by default. This
2016-05-11 03:48:16 -04:00
allows 3rd party developers and users to improve their xonsh experience without
2016-05-11 01:55:53 -04:00
having to go through the xonsh development and release cycle.
2016-05-11 03:48:16 -04:00
Many tools and libraries have extension capabilities. Here are some that we
2016-05-11 01:55:53 -04:00
took inspiration from for xonsh:
* `Sphinx <http://sphinx-doc.org/>`_: Extensions are just Python modules,
2016-05-11 03:48:16 -04:00
bundles some extensions with the main package, interface is a list of
2016-05-11 01:55:53 -04:00
string names.
* `Oh My Zsh <http://ohmyz.sh/>`_: Centralized registry, autoloading, and
for a shell.
* `ESLint <http://eslint.org/>`_: Ability to use language package manager
to install/remove extensions.
2016-05-11 02:49:03 -04:00
2016-05-11 01:55:53 -04:00
Structure
==========
2016-05-11 02:49:03 -04:00
Xontribs are modules written in either xonsh (``*.xsh``) or Python (``*.py``).
Normally, these are stored and found in an
`implicit namespace package <https://www.python.org/dev/peps/pep-0420/>`_
called ``xontrib``. However, xontribs may be placed in any package or directory
that is on the ``$PYTHONPATH``.
2016-05-11 03:48:16 -04:00
If a module is in the ``xontrib`` namespace package, it can be referred to just
2016-05-11 02:49:03 -04:00
by its module name. If a module is in any other package, then it must be
2016-05-11 03:48:16 -04:00
referred to by its full package path, separated by ``.`` like you would in an
import statement. Of course, a module in ``xontrib`` may be referred to
2016-05-11 02:49:03 -04:00
with the full ``xontrib.myext``. But just calling it ``myext`` is a lot shorter
and one of the main advantages of placing an extension in the ``xontrib``
namespace package.
Here is a sample file system layout and what the xontrib names would be::
|- xontrib/
|- javert.xsh # "javert", because in xontrib
|- your.py # "your",
|- eyes/
|- __init__.py
|- scream.xsh # "eyes.scream", because eyes is in xontrib
|- mypkg/
|- __init__.py # a regular package with an init file
|- other.py # not a xontrib
|- show.py # "mypkg.show", full module name
|- tell.xsh # "mypkg.tell", full module name
|- subpkg/
|- __init__.py
|- done.py # "mypkg.subpkg.done", full module name
You can also use `cookiecutter <https://github.com/audreyr/cookiecutter>`_ with
the `xontrib template <https://github.com/xonsh/xontrib-cookiecutter>`_ to easily
create the layout for your xontrib package.
2016-05-11 02:49:03 -04:00
Loading Xontribs
================
2022-05-05 00:32:20 +05:30
Xontribs may be loaded in a few different ways: from the config file
(e.g. ``~/.config/xonsh/rc.xsh``), dynamically at runtime with
the ``xontrib`` command, or by importing the
2016-05-11 02:49:03 -04:00
module normally. Since these extensions are just Python modules, by
default, they cannot be unloaded (easily).
.. note::
When a xontrib is loaded its public variables are placed in the current
execution context unless ``__all__`` is defined, just like in regular Python
modules.
2016-05-11 02:49:03 -04:00
Extensions are loaded via the ``xontrib`` command, which is a xonsh default
alias. This command may be run from anywhere in a xonshrc file or at any point
after xonsh has started up. Loading is the default action of the ``xontrib``
command. Thus the following methods for loading via this command are equivalent:
2016-05-11 02:49:03 -04:00
.. code-block:: xonsh
xontrib myext mpl mypkg.show
xontrib load myext mpl mypkg.show
Loading the same xontrib multiple times does not have any effect after the
first. Xontribs are simply Python modules, and therefore follow the same
caching rules. So by the same token, you can also import them normally.
Of course, you have to use the full module name to import a xontrib:
.. code-block:: python
import xontrib.mpl
from xontrib import myext
from mypkg.show import *
2016-05-11 01:55:53 -04:00
2016-05-11 03:44:39 -04:00
Listing Known Xontribs
======================
2016-05-11 12:27:50 -04:00
In addition to loading extensions, the ``xontrib`` command also allows you to
2022-05-05 00:32:20 +05:30
list the installed xontribs. This command will report if they are loaded
in the current session. To display this
2016-05-11 03:44:39 -04:00
information, pass the ``list`` action to the ``xontrib`` command:
.. code-block:: xonshcon
>>> xontrib list
2022-05-05 00:32:20 +05:30
mpl not-loaded
myext not-loaded
2016-05-11 03:44:39 -04:00
2016-05-11 03:48:16 -04:00
For programmatic access, you may also have this command print a JSON formatted
2016-05-11 03:44:39 -04:00
string:
.. code-block:: xonshcon
>>> xontrib list --json mpl
{"mpl": {"loaded": false, "installed": true}}
Authoring Xontribs
==================
2016-05-11 03:44:39 -04:00
Writing a xontrib is as easy as writing a xonsh or Python file and sticking
it in a directory named ``xontrib/``. However, please do not place an
``__init__.py`` in the ``xontrib/`` directory. It is an
*implicit namespace package* and should not have one. See
`PEP 420 <https://www.python.org/dev/peps/pep-0420/>`_ for more details.
.. warning::
Do not place an ``__init__.py`` in the ``xontrib/`` directory!
If you plan on using ``*.xsh`` files in you xontrib, then you'll
have to add some hooks to distutils, setuptools, pip, etc. to install these
files. Try adding entries like the following entries to your ``setup()`` call
in your ``setup.py``:
.. code-block:: python
try:
from setuptools import setup
except ImportError:
from distutils.core import setup
setup(...,
packages=[..., 'xontrib'],
package_dir={..., 'xontrib': 'xontrib'},
package_data={..., 'xontrib': ['*.xsh']},
...)
Something similar can be done for any non-xontrib package or sub-package
that needs to distribute ``*.xsh`` files.
2016-05-11 01:55:53 -04:00
Tell Us About Your Xontrib!
===========================
2022-05-05 00:32:20 +05:30
We request that you register your xontrib with us.
We think that will make your contribution more discoverable.
2016-05-11 03:44:39 -04:00
2022-05-05 00:32:20 +05:30
To register a xontrib, create a ``PullRequest`` at
`Awesome-xontribs <https://github.com/xonsh/awesome-xontribs>`_
repository. Also, if you use Github to host your code,
please add `xonsh <https://github.com/topics/xonsh>`_ and `xontrib <https://github.com/topics/xontrib>`_
to the topics.
2016-05-11 03:44:39 -04:00
All of this let's users know that your xontrib is out there, ready to be used.
Of course, you're under no obligation to register your xontrib. Users will
2016-05-11 03:44:39 -04:00
still be able to load your xontrib, as long as they have it installed.
Go forth!