diff --git a/.gitignore b/.gitignore index 830b2c936..e7957bf78 100644 --- a/.gitignore +++ b/.gitignore @@ -71,10 +71,6 @@ rever/ xonsh/webconfig/elm-stuff/ xonsh/webconfig/js/app.js -# venv (e.g, autovox) -venv/ -.venv/ - # VS Code .vscode/ diff --git a/docs/api/index.rst b/docs/api/index.rst index 509af85f8..97ab5ea0b 100644 --- a/docs/api/index.rst +++ b/docs/api/index.rst @@ -76,6 +76,7 @@ For those of you who want the gritty details. dumb_shell wizard xonfig + xontribs_meta codecache contexts @@ -84,6 +85,5 @@ For those of you who want the gritty details. .. toctree:: :maxdepth: 1 - mplhooks vox diff --git a/docs/api/xontribs_meta.rst b/docs/api/xontribs_meta.rst new file mode 100644 index 000000000..3e6ba9172 --- /dev/null +++ b/docs/api/xontribs_meta.rst @@ -0,0 +1,11 @@ +.. _xonsh_xontribs_meta: + +*********************************************** +Xontribs (``xonsh.xontribs_meta``) +*********************************************** + +.. automodule:: xonsh.xontribs_meta + :members: + :undoc-members: + :private-members: + diff --git a/docs/conf.py b/docs/conf.py index bbe622432..3fdc02b2a 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -17,7 +17,7 @@ os.environ["XONSH_DEBUG"] = "1" from xonsh import __version__ as XONSH_VERSION from xonsh.environ import DEFAULT_VARS, Env -from xonsh.xontribs import xontrib_metadata +from xonsh.xontribs_meta import get_xontribs from xonsh import main from xonsh.commands_cache import CommandsCache @@ -320,8 +320,8 @@ def make_envvars(): def make_xontribs(): - md = xontrib_metadata() - names = sorted(d["name"] for d in md["xontribs"] if "name" in d) + xons = get_xontribs() + names = sorted(xons) s = ".. list-table::\n" " :header-rows: 0\n\n" table = [] ncol = 5 @@ -344,33 +344,29 @@ def make_xontribs(): "-------\n\n" ) for name in names: - for d in md["xontribs"]: - if d.get("name", None) == name: - break + d = xons[name] title = name under = "." * len(title) - desc = d.get("description", "") + desc = d.description if not isinstance(desc, str): desc = "".join(desc) - pkgname = d.get("package", None) - if pkgname is None: + if d.package is None: pkg = "unknown" inst = "" usage = "" else: - pd = md["packages"].get(pkgname, {}) - pkg = pkgname - if "url" in pd: - pkg = "`{0} website <{1}>`_".format(pkg, pd["url"]) - if "license" in pd: - pkg = pkg + ", " + pd["license"] + pkg = d.package.name + if d.package.url: + pkg = "`{0} website <{1}>`_".format(pkg, d.package.url) + if d.package.license: + pkg = pkg + ", " + d.package.license inst = "" - installd = pd.get("install", {}) - if pkgname == "xonsh": + installd = d.package.install + if d.package.name == "xonsh": inst = "This xontrib is preinstalled with xonsh.\n\n" elif len(installd) > 0: inst = "**Installation:**\n\n" ".. code-block:: xonsh\n\n" - for k, v in sorted(pd.get("install", {}).items()): + for k, v in sorted(installd.items()): cmd = "\n ".join(v.split("\n")) inst += (" # install with {k}\n" " {cmd}").format( k=k, cmd=cmd @@ -387,7 +383,7 @@ def make_xontribs(): low=name.lower(), title=title, under=under, - url=d.get("url", "unknown"), + url=d.url or "unknown", desc=desc, pkg=pkg, inst=inst, diff --git a/docs/tutorial_xontrib.rst b/docs/tutorial_xontrib.rst index ce6e3396e..26621767a 100644 --- a/docs/tutorial_xontrib.rst +++ b/docs/tutorial_xontrib.rst @@ -176,46 +176,39 @@ Of course, you're under no obligation to register your xontrib. Users will still be able to load your xontrib, as long as they have it installed. To register a xontrib, add an entry to -`the xontribs.json file `_ +`the xontribs_meta.py file `_ in the main xonsh repository. A pull request is probably best, but if you are having trouble figuring it out please contact one of the xonsh devs with the relevant information. -This is a JSON file with two top-level keys: ``"xontribs"`` and ``"packages"``. +This is Python file holds classes and functions to register new Xontrib. -The ``"xontribs"`` key is a list of dictionaries that describes the xontrib -module itself. Such entries have the following structure: +The ``xontribs_meta.define_xontribs`` function returns a dictionary of all Xontribs. +A sample ``Xontrib`` definition looks like this, -.. code-block:: json +.. code-block:: python - {"xontribs": [ - {"name": "xontrib-name", - "package": "package-name", - "url": "http://example.com/api/xontrib", - "description": ["Textual description as string or list or strings ", - "enabling long content to be split over many lines."] - } - ] + { + "awesome": Xontrib( + url="http://example.com/api/xontrib", + description="Description and short intro for your xontrib." + "It can span multi-lines. " + "Feel free to use a triple quotes if you want to have line-endings.", + package=_XontribPkg( + name="xontrib-awesome", + license="BSD", + install={ + "pip": "xpip install xontrib-awesome", + "conda": "conda install xontrib-awesome", + }, + url="https://example.com/", + ), + ) } -The ``"packages"`` key, on the other hand, is a dict mapping package names -(associated with the xontrib entries) to metadata about the package. Package -entries have the following structure: +.. note:: Note that you can have as many entries in the ``"install"`` dict as you + want. Also, the keys are arbitrary labels, so feel free to pick whatever + you want. -.. code-block:: json - - {"packages": { - "package-name": { - "license": "WTFPL v1.1", - "url": "http://example", - "install": { - "conda": "conda install package-name", - "pip": "xpip install package-name"} - } - } - } - -Note that you can have as many entries in the ``"install"`` dict as you -want. Also, the keys are arbitrary labels, so feel free to pick whatever -you want. +.. seealso:: Checkout the API docs of the :doc:`api/xontribs_meta` Go forth! diff --git a/news/use-py-for-xontribs-definition.rst b/news/use-py-for-xontribs-definition.rst new file mode 100644 index 000000000..253e2e90a --- /dev/null +++ b/news/use-py-for-xontribs-definition.rst @@ -0,0 +1,23 @@ +**Added:** + +* + +**Changed:** + +* Use ``xontribs_meta.py`` instead of ``xontribs.json`` + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* diff --git a/run-tests.xsh b/run-tests.xsh index d2251d2c2..3d3e0b9aa 100755 --- a/run-tests.xsh +++ b/run-tests.xsh @@ -1,5 +1,6 @@ #!/usr/bin/env xonsh import argparse +import subprocess from typing import List @@ -7,7 +8,7 @@ $XONSH_DEBUG = 1 $RAISE_SUBPROC_ERROR = True -def _replace_args(args:List[str], num:int) -> List[str]: +def _replace_args(args: List[str], num: int) -> List[str]: return [ (arg % num) if "%d" in arg else arg for arg in args @@ -72,4 +73,7 @@ if __name__ == '__main__': qa_parser.set_defaults(func=qa) args = parser.parse_args() - args.func(args) + try: + args.func(args) + except subprocess.CalledProcessError as ex: + parser.exit(1, f"Failed with {ex}") diff --git a/setup.cfg b/setup.cfg index cc7678797..cea99446f 100644 --- a/setup.cfg +++ b/setup.cfg @@ -19,8 +19,7 @@ exclude = feedstock, rever, .venv*/, - # remove later - pygments_cache.py + .local.out*/ # lint nits that are acceptable in Xonsh project: ignore = D100, # Missing docstring in public module @@ -46,8 +45,7 @@ ignore = D411, # Missing blank line before section D407, # Missing dashed underline after section E122, - # E203 whitespace before ':' - E203, + E203, # whitespace before ':' E402, W503, # line break before binary operators is a good thing E731, # accept lambda assigned to a variable diff --git a/tests/test_xontribs.py b/tests/test_xontribs.py index 727127c13..78f470b14 100644 --- a/tests/test_xontribs.py +++ b/tests/test_xontribs.py @@ -1,12 +1,7 @@ """xontrib tests, such as they are""" import sys import pytest -from xonsh.xontribs import xontrib_metadata, xontrib_context, xontribs_load, xontribs_loaded - - -def test_load_xontrib_metadata(): - # Simply tests that the xontribs JSON files isn't malformed. - xontrib_metadata() +from xonsh.xontribs import xontrib_context, xontribs_load, xontribs_loaded @pytest.fixture @@ -78,6 +73,7 @@ hello = 'world' ctx = xontrib_context("script") assert ctx == {"hello": "world"} + def test_xontrib_load(tmpmod): """ Test that .xsh xontribs are loadable @@ -90,7 +86,8 @@ hello = 'world' ) xontribs_load(["script"]) - assert 'script' in xontribs_loaded() + assert "script" in xontribs_loaded() + def test_xontrib_load_dashed(tmpmod): """ @@ -104,5 +101,4 @@ hello = 'world' ) xontribs_load(["scri-pt"]) - assert 'scri-pt' in xontribs_loaded() - + assert "scri-pt" in xontribs_loaded() diff --git a/xonsh/__init__.py b/xonsh/__init__.py index e22964159..45afb8d83 100644 --- a/xonsh/__init__.py +++ b/xonsh/__init__.py @@ -14,6 +14,8 @@ else: try: from xonsh import __amalgam__ + xontribs_meta = __amalgam__ + _sys.modules["xonsh.xontribs_meta"] = __amalgam__ contexts = __amalgam__ _sys.modules["xonsh.contexts"] = __amalgam__ lazyasd = __amalgam__ diff --git a/xonsh/completers/xompletions.py b/xonsh/completers/xompletions.py index 5932a0811..320ab040d 100644 --- a/xonsh/completers/xompletions.py +++ b/xonsh/completers/xompletions.py @@ -1,6 +1,7 @@ """Provides completions for xonsh internal utilities""" import xonsh.xontribs as xx +import xonsh.xontribs_meta as xmt import xonsh.tools as xt from xonsh.xonfig import XONFIG_MAIN_ACTIONS @@ -21,10 +22,9 @@ def complete_xonfig(prefix, line, start, end, ctx): def _list_installed_xontribs(): - meta = xx.xontrib_metadata() + meta = xmt.get_xontribs() installed = [] - for md in meta["xontribs"]: - name = md["name"] + for name in meta: spec = xx.find_xontrib(name) if spec is not None: installed.append(spec.name.rsplit(".")[-1]) diff --git a/xonsh/webconfig/elm-compile.xsh b/xonsh/webconfig/elm-compile.xsh index 644631f25..1ba30fa6f 100755 --- a/xonsh/webconfig/elm-compile.xsh +++ b/xonsh/webconfig/elm-compile.xsh @@ -15,7 +15,7 @@ from xonsh.color_tools import rgb_to_ints from xonsh.pygments_cache import get_all_styles from xonsh.pyghooks import XonshStyle, xonsh_style_proxy, XonshHtmlFormatter, Token, XonshLexer from xonsh.prompt.base import PromptFormatter -from xonsh.xontribs import xontrib_metadata +from xonsh.xontribs_meta import get_xontribs, Xontrib $RAISE_SUBPROC_ERROR = True @@ -199,17 +199,23 @@ type alias XontribData = xontribs : List XontribData xontribs =""" + +def get_xontrib_item(xontrib_name: str, xontrib: Xontrib): + item = 'name = "' + xontrib_name + '", ' + item += 'url = "' + xontrib.url + '", ' + item += 'license = "' + (xontrib.package.license if xontrib.package else "") + '", ' + d = rst_to_html("".join(xontrib.description)).replace("\n", "\\n") + item += 'description = "' + escape(d) + '"' + return item + + def render_xontribs(lines): print_color("Rendering {GREEN}xontribs{RESET}") lines.append(xontrib_header) - md = xontrib_metadata() - packages = md["packages"] - for i, xontrib in enumerate(md["xontribs"]): - item = 'name = "' + xontrib["name"] + '", ' - item += 'url = "' + xontrib["url"] + '", ' - item += 'license = "' + packages.get(xontrib["package"], {}).get("license", "") + '", ' - d = rst_to_html("".join(xontrib["description"])).replace("\n", "\\n") - item += 'description = "' + escape(d) + '"' + md = get_xontribs() + for i, xontrib_name in enumerate(md): + xontrib = md[xontrib_name] + item = get_xontrib_item(xontrib_name, xontrib) pre = " [ " if i == 0 else " , " lines.append(pre + "{ " + item + " }") lines.append(" ]") diff --git a/xonsh/xonfig.py b/xonsh/xonfig.py index 931d5c47f..ef479e752 100644 --- a/xonsh/xonfig.py +++ b/xonsh/xonfig.py @@ -47,7 +47,8 @@ from xonsh.tools import ( color_style, ) from xonsh.foreign_shells import CANON_SHELL_NAMES -from xonsh.xontribs import xontrib_metadata, find_xontrib, xontribs_loaded +from xonsh.xontribs import find_xontrib, xontribs_loaded +from xonsh.xontribs_meta import get_xontribs, Xontrib from xonsh.lazyasd import lazyobject HR = "'`-.,_,.-*'`-.,_,.-*'`-.,_,.-*'`-.,_,.-*'`-.,_,.-*'`-.,_,.-*'`-.,_,.-*'" @@ -356,25 +357,23 @@ def _xontrib_path(visitor=None, node=None, val=None): return ("xontribs", len(visitor.state.get("xontribs", ()))) -def make_xontrib(xontrib, package): +def make_xontrib(name: str, xontrib: Xontrib): """Makes a message and StoreNonEmpty node for a xontrib.""" - name = xontrib.get("name", "") + name = name or "" msg = "\n{BOLD_CYAN}" + name + "{RESET}\n" - if "url" in xontrib: - msg += "{RED}url:{RESET} " + xontrib["url"] + "\n" - if "package" in xontrib: - msg += "{RED}package:{RESET} " + xontrib["package"] + "\n" - if "url" in package: - if "url" in xontrib and package["url"] != xontrib["url"]: - msg += "{RED}package-url:{RESET} " + package["url"] + "\n" - if "license" in package: - msg += "{RED}license:{RESET} " + package["license"] + "\n" + if xontrib.url: + msg += "{RED}url:{RESET} " + xontrib.url + "\n" + if xontrib.package: + pkg = xontrib.package + msg += "{RED}package:{RESET} " + pkg.name + "\n" + if pkg.url: + if xontrib.url and pkg.url != xontrib.url: + msg += "{RED}package-url:{RESET} " + pkg.url + "\n" + if pkg.license: + msg += "{RED}license:{RESET} " + pkg.license + "\n" msg += "{PURPLE}installed?{RESET} " msg += ("no" if find_xontrib(name) is None else "yes") + "\n" - desc = xontrib.get("description", "") - if not isinstance(desc, str): - desc = "".join(desc) - msg += _wrap_paragraphs(desc, width=69) + msg += _wrap_paragraphs(xontrib.description, width=69) if msg.endswith("\n"): msg = msg[:-1] mnode = wiz.Message(message=msg) @@ -385,10 +384,7 @@ def make_xontrib(xontrib, package): def make_xontribs_wiz(): """Makes a xontrib wizard.""" - md = xontrib_metadata() - pkgs = [md["packages"].get(d.get("package", None), {}) for d in md["xontribs"]] - w = _make_flat_wiz(make_xontrib, md["xontribs"], pkgs) - return w + return _make_flat_wiz(make_xontrib, get_xontribs().items()) def make_xonfig_wizard(default_file=None, confirm=False, no_wizard_file=None): diff --git a/xonsh/xontribs.json b/xonsh/xontribs.json deleted file mode 100644 index d7826107c..000000000 --- a/xonsh/xontribs.json +++ /dev/null @@ -1,584 +0,0 @@ -{"xontribs": [ - {"name": "abbrevs", - "package": "xonsh", - "url": "http://xon.sh", - "description": [ - "Adds ``abbrevs`` dictionary to hold user-defined command abbreviations. ", - "The dictionary is searched as you type and the matching words are replaced ", - "at the command line by the corresponding dictionary contents once you hit ", - "'Space' or 'Return' key. For instance a frequently used command such as ", - "``git status`` can be abbreviated to ``gst`` as follows::\n\n", - " $ xontrib load abbrevs\n", - " $ abbrevs['gst'] = 'git status'\n", - " $ gst # Once you hit or , 'gst' gets expanded to 'git status'.\n\n"] - }, - {"name": "apt_tabcomplete", - "package": "xonsh-apt-tabcomplete", - "url": "https://github.com/DangerOnTheRanger/xonsh-apt-tabcomplete", - "description": ["Adds tabcomplete functionality to apt-get/apt-cache inside of xonsh."] - }, - {"name": "argcomplete", - "package": "xontrib-argcomplete", - "url": "https://github.com/anki-code/xontrib-argcomplete", - "description": ["Argcomplete support to tab completion of python and xonsh scripts in xonsh."] - }, - {"name": "autojump", - "package": "xontrib-autojump", - "url": "https://github.com/sagartewari01/autojump-xonsh", - "description": ["autojump support for xonsh"] - }, - {"name": "autovox", - "package": "xonsh", - "url": "http://xon.sh", - "description": ["Manages automatic activation of virtual environments."] - }, - {"name": "autoxsh", - "package": "xonsh-autoxsh", - "url": "https://github.com/Granitas/xonsh-autoxsh", - "description": ["Adds automatic execution of xonsh script files called ", - "``.autoxsh`` when enterting a directory with ``cd`` function"] - }, - {"name": "avox", - "package": "xontrib-avox", - "url": "https://github.com/AstraLuma/xontrib-avox", - "description": ["Automatic (de)activation of virtual environments as you cd around"] - }, - {"name": "back2dir", - "package": "xontrib-back2dir", - "url": "https://github.com/anki-code/xontrib-back2dir", - "description": [ - "Return to the most recently used directory when starting the xonsh shell. ", - "For example, if you were in the '/work' directory when you last exited xonsh, ", - "then your next xonsh session will start in the '/work' directory, instead of your home directory."] - }, - {"name": "bashisms", - "package": "xonsh", - "url": "http://xon.sh", - "description": [ - "Enables additional Bash-like syntax while at the command prompt. For ", - "example, the ``!!`` syntax for running the previous command is now usable. ", - "Note that these features are implemented as precommand events and these ", - "additions do not affect the xonsh language when run as script. That said, ", - "you might find them useful if you have strong muscle memory.\n\n", - "**Warning:** This xontrib may modify user command line input to implement ", - "its behavior. To see the modifications as they are applied (in unified diff", - "format), please set ``$XONSH_DEBUG`` to ``2`` or higher.\n\n", - "The xontrib also adds commands: ``alias``, ``export``, ``unset``, ``set``, ``shopt``, ``complete``."] - }, - {"name": "base16_shell", - "package": "xontrib-base16-shell", - "url": "https://github.com/ErickTucto/xontrib-base16-shell", - "description": ["Change base16 shell themes"] - }, - {"name": "coreutils", - "package": "xonsh", - "url": "http://xon.sh", - "description": [ - "Additional core utilities that are implemented in xonsh. The current list ", - "includes:\n", - "\n", - "* cat\n", - "* echo\n", - "* pwd\n", - "* tee\n", - "* tty\n", - "* yes\n", - "\n", - "In many cases, these may have a lower performance overhead than the ", - "posix command line utility with the same name. This is because these ", - "tools avoid the need for a full subprocess call. Additionally, these ", - "tools are cross-platform." - ] - }, - { - "name": "cmd_done", - "package": "xontrib-cmd-durations", - "url": "https://github.com/jnoortheen/xontrib-cmd-durations", - "description": [ - "send notification once long-running command is finished.", - " Adds `long_cmd_duration` field to $PROMPT_FIELDS.", - " Note: It needs `xdotool` installed to detect current window." - ] - }, - { - "name": "direnv", - "package": "xonsh-direnv", - "url": "https://github.com/74th/xonsh-direnv", - "description": [ - "Supports direnv." - ] - }, - { - "name": "hist_navigator", - "package": "xontrib-hist-navigator", - "url": "https://github.com/jnoortheen/xontrib-hist-navigator", - "description": [ - "Move through directory history with nextd and prevd also with keybindings." - ] - }, - { - "name": "distributed", - "package": "xonsh", - "url": "http://xon.sh", - "description": [ - "The distributed parallel computing library hooks for xonsh. ", - "Importantly this provides a substitute 'dworker' command which enables ", - "distributed workers to have access to xonsh builtins.\n\n", - "Furthermore, this xontrib adds a 'DSubmitter' context manager for ", - "executing a block remotely. Moreover, this also adds a convenience ", - "function 'dsubmit()' for creating DSubmitter and Executor instances ", - "at the same time. Thus users may submit distributed jobs with::\n\n", - " with dsubmit('127.0.0.1:8786', rtn='x') as dsub:\n", - " x = $(echo I am elsewhere)\n\n", - " res = dsub.future.result()\n", - " print(res)\n\n", - "This is useful for long running or non-blocking jobs." - ] - }, - {"name": "docker_tabcomplete", - "package": "xonsh-docker-tabcomplete", - "url": "https://github.com/xsteadfastx/xonsh-docker-tabcomplete", - "description": ["Adds tabcomplete functionality to docker inside of xonsh."] - }, - {"name": "free_cwd", - "package": "xonsh", - "url": "http://xon.sh", - "description": [ - "Windows only xontrib, to release the lock on the current directory ", - "whenever the prompt is shown. Enabling this will allow the other ", - "programs or Windows Explorer to delete or rename the current or parent ", - "directories. Internally, it is accomplished by temporarily resetting ", - "CWD to the root drive folder while waiting at the prompt. This only ", - "works with the prompt_toolkit backend and can cause cause issues ", - "if any extensions are enabled that hook the prompt and relies on ", - "``os.getcwd()``"] - }, - {"name": "fzf-widgets", - "package": "xontrib-fzf-widgets", - "url": "https://github.com/laloch/xontrib-fzf-widgets", - "description": ["Adds some fzf widgets to your xonsh shell."] - }, - {"name": "gitinfo", - "package": "xontrib-gitinfo", - "url": "https://github.com/dyuri/xontrib-gitinfo", - "description": ["Displays git information on entering a repository folder. Uses ``onefetch`` if available."] - }, - {"name": "histcpy", - "package": "xontrib-histcpy", - "url": "https://github.com/con-f-use/xontrib-histcpy", - "description": [ - "Useful aliases and shortcuts for extracting links and text", - "from command output history and putting them into the", - " clipboard."] - }, - {"name": "jedi", - "package": "xonsh", - "url": "http://xon.sh", - "description": ["Use Jedi as xonsh's python completer."] - }, - {"name": "kitty", - "package": "xontrib-kitty", - "url": "https://github.com/scopatz/xontrib-kitty", - "description": ["Xonsh hooks for the Kitty terminal emulator."] - }, - {"name": "mpl", - "package": "xonsh", - "url": "http://xon.sh", - "description": ["Matplotlib hooks for xonsh, including the new 'mpl' alias ", - "that displays the current figure on the screen."] - }, - {"name": "output_search", - "package": "xontrib-output-search", - "url": "https://github.com/anki-code/xontrib-output-search", - "description": ["Get identifiers, names, paths, URLs and words from the previous command output ", - "and use them for the next command."] - }, - {"name": "onepath", - "package": "xontrib-onepath", - "url": "https://github.com/anki-code/xontrib-onepath", - "description": ["When you click to a file or folder in graphical OS they will be opened in associated app.", - "The xontrib-onepath brings the same logic for the xonsh shell. Type the filename or path", - "without preceding command and an associated action will be executed. The actions are customizable."] - }, - {"name": "pdb", - "package": "xonsh", - "url": "http://xon.sh", - "description": ["Simple built-in debugger. Runs pdb on reception of SIGUSR1 signal."] - }, - {"name": "pipeliner", - "package": "xontrib-pipeliner", - "url": "https://github.com/anki-code/xontrib-pipeliner", - "description": ["Let your pipe lines flow thru the Python code in xonsh."] - }, - {"name": "powerline", - "package": "xontrib-powerline", - "url": "https://github.com/santagada/xontrib-powerline", - "description": ["Powerline for Xonsh shell"] - }, - {"name": "powerline2", - "package": "xontrib-powerline2", - "url": "https://github.com/vaaaaanquish/xontrib-powerline2", - "description": ["Powerline for Xonsh shell forked from santagada/xontrib-powerline"] - }, - {"name": "prompt_bar", - "package": "xontrib-prompt-bar", - "url": "https://github.com/anki-code/xontrib-prompt-bar", - "description": ["An elegance bar style for prompt."] - }, - {"name": "powerline_binding", - "package": "xontrib-powerline-binding", - "url": "https://github.com/dyuri/xontrib-powerline-binding", - "description": ["Uses powerline to render the xonsh prompt"] - }, - {"name": "prompt_ret_code", - "package": "xonsh", - "url": "http://xon.sh", - "description": ["Adds return code info to the prompt"] - }, - {"name": "prompt_vi_mode", - "package": "xontrib-prompt-vi-mode", - "url": "https://github.com/t184256/xontrib-prompt-vi-mode", - "description": ["vi-mode status formatter for xonsh prompt"] - }, - {"name": "pyenv", - "package": "xontrib-pyenv", - "url": "https://github.com/dyuri/xontrib-pyenv", - "description": ["pyenv integration for xonsh."] - }, - {"name": "readable-traceback", - "package": "xontrib-readable-traceback", - "url": "https://github.com/6syun9/xontrib-readable-traceback", - "description": ["Make traceback easier to see for xonsh."] - }, - {"name": "sh", - "package": "xontrib-sh", - "url": "https://github.com/anki-code/xontrib-sh", - "description": ["Paste and run commands from bash, zsh, fish in xonsh shell."] - }, - {"name": "schedule", - "package": "xontrib-schedule", - "url": "https://github.com/AstraLuma/xontrib-schedule", - "description": ["Xonsh Task Scheduling"] - }, - {"name": "scrapy_tabcomplete", - "package": "xonsh-scrapy-tabcomplete", - "url": "https://github.com/Granitas/xonsh-scrapy-tabcomplete", - "description": ["Adds tabcomplete functionality to scrapy inside of xonsh."] - }, - {"name": "ssh_agent", - "package": "xontrib-ssh-agent", - "url": "https://github.com/dyuri/xontrib-ssh-agent", - "description": ["ssh-agent integration"] - }, - {"name": "vox", - "package": "xonsh", - "url": "http://xon.sh", - "description": ["Python virtual environment manager for xonsh."] - }, - {"name": "vox_tabcomplete", - "package": "xonsh-vox-tabcomplete", - "url": "https://github.com/Granitosaurus/xonsh-vox-tabcomplete", - "description": ["Adds tabcomplete functionality to vox inside of xonsh."] - }, - {"name": "whole_word_jumping", - "package": "xonsh", - "url": "http://xon.sh", - "description": [ - "Jumping across whole words (non-whitespace) with Ctrl+Left/Right. ", - "Alt+Left/Right remains unmodified to jump over smaller word segments. ", - "Shift+Delete removes the whole word."] - }, - {"name": "xo", - "package": "exofrills", - "url": "https://github.com/scopatz/xo", - "description": ["Adds an 'xo' alias to run the exofrills text editor in the ", - "current Python interpreter session. This shaves off a ", - "bit of the startup time when running your favorite, minimal ", - "text editor."] - }, - {"name": "xog", - "package": "xonsh", - "url": "http://xon.sh", - "description": ["Adds a simple command to establish and print temporary traceback log file."] - }, - {"name": "xpg", - "package": "xontrib-xpg", - "url": "https://github.com/fengttt/xsh/tree/master/py", - "description": ["Run/plot/explain sql query for PostgreSQL."] - }, - {"name": "z", - "package": "xontrib-z", - "url": "https://github.com/AstraLuma/xontrib-z", - "description": ["Tracks your most used directories, based on 'frecency'."] - }, - {"name": "zoxide", - "package": "xontrib-zoxide", - "url": "https://github.com/dyuri/xontrib-zoxide", - "description": ["Zoxide integration for xonsh."] - } - ], - "packages": { - "exofrills": { - "license": "WTFPL", - "url": "http://exofrills.org", - "install": { - "conda": "conda install -c conda-forge xo", - "pip": "xpip install exofrills"} - }, - "xonsh": { - "license": "BSD 3-clause", - "url": "http://xon.sh", - "install": { - "conda": "conda install -c conda-forge xonsh", - "pip": "xpip install xonsh", - "aura": "sudo aura -A xonsh", - "yaourt": "yaourt -Sa xonsh"} - }, - "xontrib-argcomplete": { - "license": "BSD", - "url": "https://github.com/anki-code/xontrib-argcomplete", - "install": { - "pip": "xpip install xontrib-argcomplete" - } - }, - "xontrib-back2dir": { - "license": "BSD", - "url": "https://github.com/anki-code/xontrib-back2dir", - "install": { - "pip": "xpip install xontrib-back2dir" - } - }, - "xonsh-autoxsh": { - "license": "GPLv3", - "url": "https://github.com/Granitas/xonsh-autoxsh", - "install": { - "pip": "xpip install xonsh-autoxsh" - } - }, - "xonsh-apt-tabcomplete": { - "license": "BSD 2-clause", - "url": "https://github.com/DangerOnTheRanger/xonsh-apt-tabcomplete", - "install": { - "pip": "xpip install xonsh-apt-tabcomplete" - } - }, - "xonsh-click-tabcomplete": { - "license": "GPLv3", - "url": "https://github.com/Granitosaurus/xonsh-click-tabcomplete", - "install": { - "pip": "xpip install xonsh-click-tabcomplete" - } - }, - "xonsh-direnv": { - "license": "MIT", - "url": "https://github.com/74th/xonsh-direnv", - "install": { - "pip": "xpip install xonsh-direnv" - } - }, - "xonsh-docker-tabcomplete": { - "license": "MIT", - "url": "https://github.com/xsteadfastx/xonsh-docker-tabcomplete", - "install": { - "pip": "xpip install xonsh-docker-tabcomplete" - } - }, - "xontrib-hist-navigator": { - "license": "MIT", - "url": "https://github.com/jnoortheen/xontrib-hist-navigator", - "install": { - "pip": "xpip install xontrib-hist-navigator" - } - }, - "xonsh-scrapy-tabcomplete": { - "license": "GPLv3", - "url": "https://github.com/Granitas/xonsh-scrapy-tabcomplete", - "install": { - "pip": "xpip install xonsh-scrapy-tabcomplete" - } - }, - "xonsh-vox-tabcomplete": { - "license": "GPLv3", - "url": "https://github.com/Granitosaurus/xonsh-vox-tabcomplete", - "install": { - "pip": "xpip install xonsh-vox-tabcomplete" - } - }, - "xonda": { - "license": "MIT", - "url": "https://github.com/gforsyth/xonda", - "install": { - "pip": "xpip install xonda" - } - }, - "xontrib-avox": { - "license": "GPLv3", - "url": "https://github.com/AstraLuma/xontrib-avox", - "install": { - "pip": "xpip install xontrib-avox" - } - }, - "xontrib-cmd-durations": { - "license": "MIT", - "url": "https://github.com/jnoortheen/xontrib-cmd-durations", - "install": { - "pip": "xpip install xontrib-cmd-durations" - } - }, - "xontrib-fzf-widgets": { - "license": "GPLv3", - "url": "https://github.com/laloch/xontrib-fzf-widgets", - "install": { - "pip": "xpip install xontrib-fzf-widgets" - } - }, - "xontrib-gitinfo": { - "license": "MIT", - "url": "https://github.com/dyuri/xontrib-gitinfo", - "install": { - "pip": "xpip install xontrib-gitinfo" - } - }, - "xontrib-histcpy": { - "license": "GPLv3", - "url": "https://github.com/con-f-use/xontrib-histcpy", - "install": { - "pip": "xpip install xontrib-histcpy" - } - }, - "xontrib-kitty": { - "license": "BSD-3-Clause", - "url": "https://github.com/scopatz/xontrib-kitty", - "install": { - "conda": "conda install -c conda-forge xontrib-kitty", - "pip": "xpip install xontrib-kitty" - } - }, - "xontrib-output-search": { - "license": "BSD", - "url": "https://github.com/tokenizer/xontrib-output-search", - "install": { - "pip": "xpip install xontrib-output-search" - } - }, - "xontrib-onepath": { - "license": "BSD", - "url": "https://github.com/anki-code/xontrib-onepath", - "install": { - "pip": "xpip install xontrib-onepath" - } - }, - "xontrib-pipeliner": { - "license": "MIT", - "url": "https://github.com/anki-code/xontrib-pipeliner", - "install": { - "pip": "xpip install xontrib-pipeliner" - } - }, - "xontrib-powerline": { - "license": "MIT", - "url": "https://github.com/santagada/xontrib-powerline", - "install": { - "pip": "xpip install xontrib-powerline" - } - }, - "xontrib-powerline2": { - "license": "MIT", - "url": "https://github.com/vaaaaanquish/xontrib-powerline2", - "install": { - "pip": "xpip install xontrib-powerline2" - } - }, - "xontrib-powerline-binding": { - "license": "MIT", - "url": "https://github.com/dyuri/xontrib-powerline-binding", - "install": { - "pip": "xpip install xontrib-powerline-binding" - } - }, - "xontrib-prompt-bar": { - "license": "MIT", - "url": "https://github.com/anki-code/xontrib-prompt-bar", - "install": { - "pip": "xpip install xontrib-prompt-bar" - } - }, - "xontrib-prompt-ret-code": { - "license": "MIT", - "url": "https://github.com/Siecje/xontrib-prompt-ret-code", - "install": { - "pip": "xpip install xontrib-prompt-ret-code" - } - }, - "xontrib-prompt-vi-mode": { - "license": "MIT", - "url": "https://github.com/t184256/xontrib-prompt-vi-mode", - "install": { - "pip": "xpip install xontrib-prompt-vi-mode" - } - }, - "xontrib-pyenv": { - "license": "MIT", - "url": "https://github.com/dyuri/xontrib-pyenv", - "install": { - "pip": "xpip install xontrib-pyenv" - } - }, - "xontrib-readable-traceback": { - "license": "MIT", - "url": "https://github.com/6syun9/xontrib-readable-traceback", - "install": { - "pip": "xpip install xontrib-readable-traceback" - } - }, - "xontrib-sh": { - "license": "MIT", - "url": "https://github.com/anki-code/xontrib-sh", - "install": { - "pip": "xpip install xontrib-sh" - } - }, - "xontrib-schedule": { - "license": "MIT", - "url": "https://github.com/AstraLuma/xontrib-schedule", - "install": { - "pip": "xpip install xontrib-schedule" - } - }, - "xontrib-ssh-agent": { - "license": "MIT", - "url": "https://github.com/dyuri/xontrib-ssh-agent", - "install": { - "pip": "xpip install xontrib-ssh-agent" - } - }, - "xontrib-thefuck": { - "license": "MIT", - "url": "https://github.com/meatballs/xontrib-thefuck", - "install": { - "pip": "xpip install xontrib-thefuck" - } - }, - "xontrib-xpg": { - "license": "Apache", - "url": "https://github.com/fengttt/xsh/py", - "install": { - "pip": "xpip install xontrib-xpg" - } - }, - "xontrib-z": { - "license": "GPLv3", - "url": "https://github.com/AstraLuma/xontrib-z", - "install": { - "pip": "xpip install xontrib-z" - } - }, - "xontrib-zoxide": { - "license": "MIT", - "url": "https://github.com/dyuri/xontrib-zoxide", - "install": { - "pip": "xpip install xontrib-zoxide" - } - } - } -} diff --git a/xonsh/xontribs.py b/xonsh/xontribs.py index 12eaf73ec..6930dad3b 100644 --- a/xonsh/xontribs.py +++ b/xonsh/xontribs.py @@ -1,17 +1,18 @@ """Tools for helping manage xontributions.""" -import os -import sys -import json -import builtins import argparse +import builtins import functools import importlib import importlib.util - +import json +import sys +import typing as tp from enum import IntEnum -from xonsh.tools import print_color, print_exception, unthreadable from pathlib import Path +from xonsh.xontribs_meta import get_xontribs +from xonsh.tools import print_color, print_exception, unthreadable + class ExitCode(IntEnum): OK = 0 @@ -42,14 +43,15 @@ def xontrib_context(name): return ctx -def prompt_xontrib_install(names): +def prompt_xontrib_install(names: tp.List[str]): """Returns a formatted string with name of xontrib package to prompt user""" - md = xontrib_metadata() + xontribs = get_xontribs() packages = [] for name in names: - for xontrib in md["xontribs"]: - if xontrib["name"] == name: - packages.append(xontrib["package"]) + if name in xontribs: + xontrib = xontribs[name] + if xontrib.package: + packages.append(xontrib.package.name) print( "The following xontribs are enabled but not installed: \n" @@ -76,44 +78,6 @@ def update_context(name, ctx=None): return ctx.update(modctx) -@functools.lru_cache() -def xontrib_metadata(): - """Loads and returns the xontribs.json file.""" - impres = None - pkg_resources = None - - # NOTE: Reduce all of these alternate implementations when the minimum Python - # is >=3.7 - try: - # Python 3.7 - import importlib.resources as impres - except ImportError: - try: - # Optional backport for <3.7 - import importlib_resources as impres - except ImportError: - try: - # Try the slower and clunkier pkg_resources - # This is only available if setuptools is part of the environment - import pkg_resources - except ImportError: - pass - - if impres: - with impres.open_text("xonsh", "xontribs.json") as f: - md = json.load(f) - elif pkg_resources: - # Despite the name, this is a bytes - bytesdata = pkg_resources.resource_string("xonsh", "xontribs.json") - md = json.loads(bytesdata.decode("utf-8")) - else: - path = os.path.join(os.path.dirname(__file__), "xontribs.json") - with open(path, "r") as f: - md = json.load(f) - - return md - - def xontribs_load(names, verbose=False): """Load xontribs from a list of names""" ctx = builtins.__xonsh__.ctx @@ -138,39 +102,39 @@ def _load(ns): return xontribs_load(ns.names, verbose=ns.verbose) -def xontrib_installed(ns=None): +def xontrib_installed(names: tp.Set[str]): """Returns list of installed xontribs.""" installed_xontribs = set() - xontrib_locations = importlib.util.find_spec("xontrib").submodule_search_locations - names = None if not ns or len(ns.names) == 0 else set(ns.names) - if xontrib_locations: - for xl in xontrib_locations: - for x in Path(xl).glob("*"): - name = x.name.split(".")[0] - if name[0] == "_" or (names and name not in names): - continue - installed_xontribs.add(name) + spec = importlib.util.find_spec("xontrib") + if spec: + xontrib_locations = spec.submodule_search_locations + if xontrib_locations: + for xl in xontrib_locations: + for x in Path(xl).glob("*"): + name = x.name.split(".")[0] + if name[0] == "_" or (names and name not in names): + continue + installed_xontribs.add(name) return installed_xontribs def xontrib_data(ns): """Collects and returns the data about xontribs.""" - meta = xontrib_metadata() + meta = get_xontribs() data = {} - names = None if not ns or len(ns.names) == 0 else set(ns.names) - for md in meta["xontribs"]: - name = md["name"] - if names is not None and md["name"] not in names: + names: tp.Set[str] = set() if not ns else set(ns.names) + for xo_name in meta: + if xo_name not in names: continue - spec = find_xontrib(name) + spec = find_xontrib(xo_name) if spec is None: installed = loaded = False else: installed = True loaded = spec.name in sys.modules - data[name] = {"name": name, "installed": installed, "loaded": loaded} + data[xo_name] = {"name": xo_name, "installed": installed, "loaded": loaded} - installed_xontribs = xontrib_installed(ns) + installed_xontribs = xontrib_installed(names) for name in installed_xontribs: if name not in data: loaded = f"xontrib.{name}" in sys.modules diff --git a/xonsh/xontribs_meta.py b/xonsh/xontribs_meta.py new file mode 100644 index 000000000..56fb46624 --- /dev/null +++ b/xonsh/xontribs_meta.py @@ -0,0 +1,583 @@ +""" +This modules is the place where one would define the xontribs. +""" + +import functools +import typing as tp + + +class _XontribPkg(tp.NamedTuple): + """Class to define package information of a xontrib. + + Attributes + ---------- + install + a mapping of tools with respective install commands. e.g. {"pip": "pip install xontrib"} + license + license type of the xontrib package + name + full name of the package. e.g. "xontrib-argcomplete" + url + URL to the homepage of the xontrib package. + """ + + install: tp.Dict[str, str] + license: str = "" + name: str = "" + url: tp.Optional[str] = None + + +class Xontrib(tp.NamedTuple): + """Meta class that is used to describe xontribs. + + Attributes + ---------- + url + url to the home page of the xontrib. + description + short description about the xontrib. + package + pkg information for installing the xontrib + tags + category. + """ + + url: str = "" + description: str = "" + package: tp.Optional[_XontribPkg] = None + tags: tp.Tuple[str, ...] = () + + +@functools.lru_cache() +def get_xontribs() -> tp.Dict[str, Xontrib]: + """Return xontrib definitions lazily.""" + return define_xontribs() + + +def define_xontribs(): + """Xontrib registry.""" + core_pkg = _XontribPkg( + name="xonsh", + license="BSD 3-clause", + install={ + "conda": "conda install -c conda-forge xonsh", + "pip": "xpip install xonsh", + "aura": "sudo aura -A xonsh", + "yaourt": "yaourt -Sa xonsh", + }, + url="http://xon.sh", + ) + return { + "abbrevs": Xontrib( + url="http://xon.sh", + description="Adds ``abbrevs`` dictionary to hold user-defined " + "command abbreviations. The dictionary is searched " + "as you type and the matching words are replaced " + "at the command line by the corresponding " + "dictionary contents once you hit 'Space' or " + "'Return' key. For instance a frequently used " + "command such as ``git status`` can be abbreviated " + "to ``gst`` as follows::\n" + "\n" + " $ xontrib load abbrevs\n" + " $ abbrevs['gst'] = 'git status'\n" + " $ gst # Once you hit or , " + "'gst' gets expanded to 'git status'.\n" + "\n", + package=core_pkg, + ), + "apt_tabcomplete": Xontrib( + url="https://github.com/DangerOnTheRanger/xonsh-apt-tabcomplete", + description="Adds tabcomplete functionality to " + "apt-get/apt-cache inside of xonsh.", + package=_XontribPkg( + name="xonsh-apt-tabcomplete", + license="BSD 2-clause", + install={"pip": "xpip install xonsh-apt-tabcomplete"}, + url="https://github.com/DangerOnTheRanger/xonsh-apt-tabcomplete", + ), + ), + "argcomplete": Xontrib( + url="https://github.com/anki-code/xontrib-argcomplete", + description="Argcomplete support to tab completion of " + "python and xonsh scripts in xonsh.", + package=_XontribPkg( + name="xontrib-argcomplete", + license="BSD", + install={"pip": "xpip install xontrib-argcomplete"}, + url="https://github.com/anki-code/xontrib-argcomplete", + ), + ), + "autojump": Xontrib( + url="https://github.com/sagartewari01/autojump-xonsh", + description="autojump support for xonsh", + ), + "autovox": Xontrib( + url="http://xon.sh", + description="Manages automatic activation of virtual " "environments.", + package=core_pkg, + ), + "autoxsh": Xontrib( + url="https://github.com/Granitas/xonsh-autoxsh", + description="Adds automatic execution of xonsh script files " + "called ``.autoxsh`` when enterting a directory " + "with ``cd`` function", + package=_XontribPkg( + name="xonsh-autoxsh", + license="GPLv3", + install={"pip": "xpip install xonsh-autoxsh"}, + url="https://github.com/Granitas/xonsh-autoxsh", + ), + ), + "avox": Xontrib( + url="https://github.com/AstraLuma/xontrib-avox", + description="Automatic (de)activation of virtual environments as " + "you cd around", + package=_XontribPkg( + name="xontrib-avox", + license="GPLv3", + install={"pip": "xpip install xontrib-avox"}, + url="https://github.com/AstraLuma/xontrib-avox", + ), + ), + "back2dir": Xontrib( + url="https://github.com/anki-code/xontrib-back2dir", + description="Return to the most recently used directory when " + "starting the xonsh shell. For example, if you " + "were in the '/work' directory when you last " + "exited xonsh, then your next xonsh session will " + "start in the '/work' directory, instead of your " + "home directory.", + package=_XontribPkg( + name="xontrib-back2dir", + license="BSD", + install={"pip": "xpip install xontrib-back2dir"}, + url="https://github.com/anki-code/xontrib-back2dir", + ), + ), + "base16_shell": Xontrib( + url="https://github.com/ErickTucto/xontrib-base16-shell", + description="Change base16 shell themes", + ), + "bashisms": Xontrib( + url="http://xon.sh", + description="Enables additional Bash-like syntax while at the " + "command prompt. For example, the ``!!`` syntax " + "for running the previous command is now usable. " + "Note that these features are implemented as " + "precommand events and these additions do not " + "affect the xonsh language when run as script. " + "That said, you might find them useful if you " + "have strong muscle memory.\n" + "\n" + "**Warning:** This xontrib may modify user " + "command line input to implement its behavior. To " + "see the modifications as they are applied (in " + "unified diffformat), please set ``$XONSH_DEBUG`` " + "to ``2`` or higher.\n" + "\n" + "The xontrib also adds commands: ``alias``, " + "``export``, ``unset``, ``set``, ``shopt``, " + "``complete``.", + package=core_pkg, + ), + "cmd_done": Xontrib( + url="https://github.com/jnoortheen/xontrib-cmd-durations", + description="send notification once long-running command is " + "finished. Adds `long_cmd_duration` field to " + "$PROMPT_FIELDS. Note: It needs `xdotool` " + "installed to detect current window.", + package=_XontribPkg( + name="xontrib-cmd-durations", + license="MIT", + install={"pip": "xpip install xontrib-cmd-durations"}, + url="https://github.com/jnoortheen/xontrib-cmd-durations", + ), + ), + "coreutils": Xontrib( + url="http://xon.sh", + description="Additional core utilities that are implemented " + "in xonsh. The current list includes:\n" + "\n" + "* cat\n" + "* echo\n" + "* pwd\n" + "* tee\n" + "* tty\n" + "* yes\n" + "\n" + "In many cases, these may have a lower " + "performance overhead than the posix command " + "line utility with the same name. This is " + "because these tools avoid the need for a full " + "subprocess call. Additionally, these tools are " + "cross-platform.", + package=core_pkg, + ), + "direnv": Xontrib( + url="https://github.com/74th/xonsh-direnv", + description="Supports direnv.", + package=_XontribPkg( + name="xonsh-direnv", + license="MIT", + install={"pip": "xpip install xonsh-direnv"}, + url="https://github.com/74th/xonsh-direnv", + ), + ), + "distributed": Xontrib( + url="http://xon.sh", + description="The distributed parallel computing library " + "hooks for xonsh. Importantly this provides a " + "substitute 'dworker' command which enables " + "distributed workers to have access to xonsh " + "builtins.\n" + "\n" + "Furthermore, this xontrib adds a 'DSubmitter' " + "context manager for executing a block " + "remotely. Moreover, this also adds a " + "convenience function 'dsubmit()' for creating " + "DSubmitter and Executor instances at the same " + "time. Thus users may submit distributed jobs " + "with::\n" + "\n" + " with dsubmit('127.0.0.1:8786', rtn='x') " + "as dsub:\n" + " x = $(echo I am elsewhere)\n" + "\n" + " res = dsub.future.result()\n" + " print(res)\n" + "\n" + "This is useful for long running or " + "non-blocking jobs.", + package=core_pkg, + ), + "docker_tabcomplete": Xontrib( + url="https://github.com/xsteadfastx/xonsh-docker-tabcomplete", + description="Adds tabcomplete functionality to " "docker inside of xonsh.", + package=_XontribPkg( + name="xonsh-docker-tabcomplete", + license="MIT", + install={"pip": "xpip install xonsh-docker-tabcomplete"}, + url="https://github.com/xsteadfastx/xonsh-docker-tabcomplete", + ), + ), + "free_cwd": Xontrib( + url="http://xon.sh", + description="Windows only xontrib, to release the lock on the " + "current directory whenever the prompt is shown. " + "Enabling this will allow the other programs or " + "Windows Explorer to delete or rename the current " + "or parent directories. Internally, it is " + "accomplished by temporarily resetting CWD to the " + "root drive folder while waiting at the prompt. " + "This only works with the prompt_toolkit backend " + "and can cause cause issues if any extensions are " + "enabled that hook the prompt and relies on " + "``os.getcwd()``", + package=core_pkg, + ), + "fzf-widgets": Xontrib( + url="https://github.com/laloch/xontrib-fzf-widgets", + description="Adds some fzf widgets to your xonsh shell.", + package=_XontribPkg( + name="xontrib-fzf-widgets", + license="GPLv3", + install={"pip": "xpip install xontrib-fzf-widgets"}, + url="https://github.com/laloch/xontrib-fzf-widgets", + ), + ), + "gitinfo": Xontrib( + url="https://github.com/dyuri/xontrib-gitinfo", + description="Displays git information on entering a repository " + "folder. Uses ``onefetch`` if available.", + package=_XontribPkg( + name="xontrib-gitinfo", + license="MIT", + install={"pip": "xpip install xontrib-gitinfo"}, + url="https://github.com/dyuri/xontrib-gitinfo", + ), + ), + "hist_navigator": Xontrib( + url="https://github.com/jnoortheen/xontrib-hist-navigator", + description="Move through directory history with nextd " + "and prevd also with keybindings.", + package=_XontribPkg( + name="xontrib-hist-navigator", + license="MIT", + install={"pip": "xpip install xontrib-hist-navigator"}, + url="https://github.com/jnoortheen/xontrib-hist-navigator", + ), + ), + "histcpy": Xontrib( + url="https://github.com/con-f-use/xontrib-histcpy", + description="Useful aliases and shortcuts for extracting links " + "and textfrom command output history and putting " + "them into the clipboard.", + package=_XontribPkg( + name="xontrib-histcpy", + license="GPLv3", + install={"pip": "xpip install xontrib-histcpy"}, + url="https://github.com/con-f-use/xontrib-histcpy", + ), + ), + "jedi": Xontrib( + url="http://xon.sh", + description="Use Jedi as xonsh's python completer.", + package=core_pkg, + ), + "kitty": Xontrib( + url="https://github.com/scopatz/xontrib-kitty", + description="Xonsh hooks for the Kitty terminal emulator.", + package=_XontribPkg( + name="xontrib-kitty", + license="BSD-3-Clause", + install={ + "conda": "conda install -c conda-forge " "xontrib-kitty", + "pip": "xpip install xontrib-kitty", + }, + url="https://github.com/scopatz/xontrib-kitty", + ), + ), + "mpl": Xontrib( + url="http://xon.sh", + description="Matplotlib hooks for xonsh, including the new 'mpl' " + "alias that displays the current figure on the screen.", + package=core_pkg, + ), + "onepath": Xontrib( + url="https://github.com/anki-code/xontrib-onepath", + description="When you click to a file or folder in graphical " + "OS they will be opened in associated app.The " + "xontrib-onepath brings the same logic for the " + "xonsh shell. Type the filename or pathwithout " + "preceding command and an associated action will " + "be executed. The actions are customizable.", + package=_XontribPkg( + name="xontrib-onepath", + license="BSD", + install={"pip": "xpip install xontrib-onepath"}, + url="https://github.com/anki-code/xontrib-onepath", + ), + ), + "output_search": Xontrib( + url="https://github.com/anki-code/xontrib-output-search", + description="Get identifiers, names, paths, URLs and " + "words from the previous command output and " + "use them for the next command.", + package=_XontribPkg( + name="xontrib-output-search", + license="BSD", + install={"pip": "xpip install xontrib-output-search"}, + url="https://github.com/tokenizer/xontrib-output-search", + ), + ), + "pdb": Xontrib( + url="http://xon.sh", + description="Simple built-in debugger. Runs pdb on reception of " + "SIGUSR1 signal.", + package=core_pkg, + ), + "pipeliner": Xontrib( + url="https://github.com/anki-code/xontrib-pipeliner", + description="Let your pipe lines flow thru the Python code " "in xonsh.", + package=_XontribPkg( + name="xontrib-pipeliner", + license="MIT", + install={"pip": "xpip install xontrib-pipeliner"}, + url="https://github.com/anki-code/xontrib-pipeliner", + ), + ), + "powerline": Xontrib( + url="https://github.com/santagada/xontrib-powerline", + description="Powerline for Xonsh shell", + package=_XontribPkg( + name="xontrib-powerline", + license="MIT", + install={"pip": "xpip install xontrib-powerline"}, + url="https://github.com/santagada/xontrib-powerline", + ), + ), + "powerline2": Xontrib( + url="https://github.com/vaaaaanquish/xontrib-powerline2", + description="Powerline for Xonsh shell forked from " + "santagada/xontrib-powerline", + package=_XontribPkg( + name="xontrib-powerline2", + license="MIT", + install={"pip": "xpip install xontrib-powerline2"}, + url="https://github.com/vaaaaanquish/xontrib-powerline2", + ), + ), + "powerline_binding": Xontrib( + url="https://github.com/dyuri/xontrib-powerline-binding", + description="Uses powerline to render the xonsh " "prompt", + package=_XontribPkg( + name="xontrib-powerline-binding", + license="MIT", + install={"pip": "xpip install xontrib-powerline-binding"}, + url="https://github.com/dyuri/xontrib-powerline-binding", + ), + ), + "prompt_bar": Xontrib( + url="https://github.com/anki-code/xontrib-prompt-bar", + description="An elegance bar style for prompt.", + package=_XontribPkg( + name="xontrib-prompt-bar", + license="MIT", + install={"pip": "xpip install xontrib-prompt-bar"}, + url="https://github.com/anki-code/xontrib-prompt-bar", + ), + ), + "prompt_ret_code": Xontrib( + url="http://xon.sh", + description="Adds return code info to the prompt", + package=core_pkg, + ), + "prompt_vi_mode": Xontrib( + url="https://github.com/t184256/xontrib-prompt-vi-mode", + description="vi-mode status formatter for xonsh prompt", + package=_XontribPkg( + name="xontrib-prompt-vi-mode", + license="MIT", + install={"pip": "xpip install xontrib-prompt-vi-mode"}, + url="https://github.com/t184256/xontrib-prompt-vi-mode", + ), + ), + "pyenv": Xontrib( + url="https://github.com/dyuri/xontrib-pyenv", + description="pyenv integration for xonsh.", + package=_XontribPkg( + name="xontrib-pyenv", + license="MIT", + install={"pip": "xpip install xontrib-pyenv"}, + url="https://github.com/dyuri/xontrib-pyenv", + ), + ), + "readable-traceback": Xontrib( + url="https://github.com/6syun9/xontrib-readable-traceback", + description="Make traceback easier to see for " "xonsh.", + package=_XontribPkg( + name="xontrib-readable-traceback", + license="MIT", + install={"pip": "xpip install xontrib-readable-traceback"}, + url="https://github.com/6syun9/xontrib-readable-traceback", + ), + ), + "schedule": Xontrib( + url="https://github.com/AstraLuma/xontrib-schedule", + description="Xonsh Task Scheduling", + package=_XontribPkg( + name="xontrib-schedule", + license="MIT", + install={"pip": "xpip install xontrib-schedule"}, + url="https://github.com/AstraLuma/xontrib-schedule", + ), + ), + "scrapy_tabcomplete": Xontrib( + url="https://github.com/Granitas/xonsh-scrapy-tabcomplete", + description="Adds tabcomplete functionality to " "scrapy inside of xonsh.", + package=_XontribPkg( + name="xonsh-scrapy-tabcomplete", + license="GPLv3", + install={"pip": "xpip install xonsh-scrapy-tabcomplete"}, + url="https://github.com/Granitas/xonsh-scrapy-tabcomplete", + ), + ), + "sh": Xontrib( + url="https://github.com/anki-code/xontrib-sh", + description="Paste and run commands from bash, zsh, fish in xonsh " + "shell.", + package=_XontribPkg( + name="xontrib-sh", + license="MIT", + install={"pip": "xpip install xontrib-sh"}, + url="https://github.com/anki-code/xontrib-sh", + ), + ), + "ssh_agent": Xontrib( + url="https://github.com/dyuri/xontrib-ssh-agent", + description="ssh-agent integration", + package=_XontribPkg( + name="xontrib-ssh-agent", + license="MIT", + install={"pip": "xpip install xontrib-ssh-agent"}, + url="https://github.com/dyuri/xontrib-ssh-agent", + ), + ), + "vox": Xontrib( + url="http://xon.sh", + description="Python virtual environment manager for xonsh.", + package=core_pkg, + ), + "vox_tabcomplete": Xontrib( + url="https://github.com/Granitosaurus/xonsh-vox-tabcomplete", + description="Adds tabcomplete functionality to vox " "inside of xonsh.", + package=_XontribPkg( + name="xonsh-vox-tabcomplete", + license="GPLv3", + install={"pip": "xpip install xonsh-vox-tabcomplete"}, + url="https://github.com/Granitosaurus/xonsh-vox-tabcomplete", + ), + ), + "whole_word_jumping": Xontrib( + url="http://xon.sh", + description="Jumping across whole words " + "(non-whitespace) with Ctrl+Left/Right. " + "Alt+Left/Right remains unmodified to " + "jump over smaller word segments. " + "Shift+Delete removes the whole word.", + package=core_pkg, + ), + "xo": Xontrib( + url="https://github.com/scopatz/xo", + description="Adds an 'xo' alias to run the exofrills text editor in " + "the current Python interpreter session. This shaves " + "off a bit of the startup time when running your " + "favorite, minimal text editor.", + package=_XontribPkg( + name="exofrills", + license="WTFPL", + install={ + "conda": "conda install -c conda-forge xo", + "pip": "xpip install exofrills", + }, + url="http://exofrills.org", + ), + ), + "xog": Xontrib( + url="http://xon.sh", + description="Adds a simple command to establish and print " + "temporary traceback log file.", + package=core_pkg, + ), + "xpg": Xontrib( + url="https://github.com/fengttt/xsh/tree/master/py", + description="Run/plot/explain sql query for PostgreSQL.", + package=_XontribPkg( + name="xontrib-xpg", + license="Apache", + install={"pip": "xpip install xontrib-xpg"}, + url="https://github.com/fengttt/xsh/py", + ), + ), + "z": Xontrib( + url="https://github.com/AstraLuma/xontrib-z", + description="Tracks your most used directories, based on 'frecency'.", + package=_XontribPkg( + name="xontrib-z", + license="GPLv3", + install={"pip": "xpip install xontrib-z"}, + url="https://github.com/AstraLuma/xontrib-z", + ), + ), + "zoxide": Xontrib( + url="https://github.com/dyuri/xontrib-zoxide", + description="Zoxide integration for xonsh.", + package=_XontribPkg( + name="xontrib-zoxide", + license="MIT", + install={"pip": "xpip install xontrib-zoxide"}, + url="https://github.com/dyuri/xontrib-zoxide", + ), + ), + }