xonsh icon indicating copy to clipboard operation
xonsh copied to clipboard

`micromamba` initialize block causes `micromamba` completions to show up for all executables

Open dotsdl opened this issue 1 year ago • 2 comments

Current Behavior

After installing micromamba through the recommended pathway, and initializing for xonsh with micromamba shell init, the following lines are added to my .xonshrc:

# >>> mamba initialize >>>
# !! Contents within this block are managed by 'mamba init' !!
$MAMBA_EXE = "/home/david/.local/bin/micromamba"
$MAMBA_ROOT_PREFIX = "/home/david/micromamba"
import sys as _sys
from types import ModuleType as _ModuleType
_mod = _ModuleType("xontrib.mamba",
                   'Autogenerated from $($MAMBA_EXE shell hook -s xonsh -p $MAMBA_ROOT_PREFIX)')
__xonsh__.execer.exec($($MAMBA_EXE shell hook -s xonsh -p $MAMBA_ROOT_PREFIX),
                      glbs=_mod.__dict__,
                      filename='$($MAMBA_EXE shell hook -s xonsh -p $MAMBA_ROOT_PREFIX)')
_sys.modules["xontrib.mamba"] = _mod
del _sys, _mod, _ModuleType
# <<< mamba initialize <<<

Starting a new shell instance, typing micromamba and hitting <TAB> yields:

image

but doing the same for another executable, e.g. rsync or vim, also yields these:

image

However, ensuring that the micromamba executable isn't in $PATH removes these completions, including from micromamba usage:

$PATH.pop('/home/david/.local/bin')

and using e.g. micromamba activate still works.

Traceback (if applicable):

# Please paste the traceback here.

Expected Behavior

I would expect that if micromamba completions show up at all, they show up only for micromamba, not for any and all executables. Any ideas as to what could be happening here?

xonfig

+-----------------------------+----------------------+
| xonsh                       | 0.17.0               |
| Python                      | 3.12.4               |
| PLY                         | 3.11                 |
| have readline               | True                 |
| prompt toolkit              | 3.0.47               |
| shell type                  | prompt_toolkit       |
| history backend             | sqlite               |
| pygments                    | 2.18.0               |
| on posix                    | True                 |
| on linux                    | True                 |
| distro                      | arch                 |
| on wsl                      | False                |
| on darwin                   | False                |
| on windows                  | False                |
| on cygwin                   | False                |
| on msys2                    | False                |
| is superuser                | False                |
| default encoding            | utf-8                |
| xonsh encoding              | utf-8                |
| encoding errors             | surrogateescape      |
| xontrib 1                   | vox                  |
| xontrib 2                   | voxapi               |
| RC file 1                   | /home/david/.xonshrc |
| UPDATE_OS_ENVIRON           | False                |
| XONSH_CAPTURE_ALWAYS        | False                |
| XONSH_SUBPROC_OUTPUT_FORMAT | stream_lines         |
| THREAD_SUBPROCS             | True                 |
| XONSH_CACHE_SCRIPTS         | True                 |
+-----------------------------+----------------------+

For community

⬇️ Please click the 👍 reaction instead of leaving a +1 or 👍 comment

dotsdl avatar Sep 26 '24 17:09 dotsdl

Hey! Thank you for reporting this! To investigate the case please use:

  • completer list to show the list of completers.
  • Review the code in micromamba shell hook -s xonsh

I think something wrong with registering the completer or/and with implementation. Thanks!

anki-code avatar Sep 26 '24 18:09 anki-code

@jnoortheen I noticed that completion is working strange sometimes e.g. returns empty list or wrong completion list. I tried to catch the cases but had no repeatable one. If you have a chance to help with this mamba case it will be cool because I think something works as not expected in new completion algorithms. (Maybe to repeat the mamba environment you can use xonsh-install.) Thanks!

anki-code avatar Sep 26 '24 18:09 anki-code

Thanks @anki-code! Sorry for the delay from me; was traveling when I reported this and lost track of it.

completer list gives:

Registered Completer Functions: (NX = Non Exclusive)

end_proc_tokens    [NX] : If there's no space following '|', '&', or ';' - insert one.
end_proc_keywords  [NX] : If there's no space following 'and' or 'or' - insert one.
environment_vars   [NX] : Completes environment variables.
base                    : If the line is empty, complete based on valid commands, python names, and paths.
skip                    : Skip over several tokens (e.g., sudo) and complete based on the rest of the
                          command.
alias                   : Complete any alias that has ``xonsh_complete`` attribute. The said attribute
                          should be a function. The current command context is
                          passed to it.
xompleter               : Lazily complete commands from `xompletions` package The base-name (case-
                          insensitive) of the executable is used to find the
                          matching completer module or the regex patterns.
import                  : Completes module names and objects for "import ..." and "from ... import ...".
micromamba              : No description provided
bash                    : Completes based on results from BASH completion.
man                     : Completes an option name, based on the contents of the associated man page.
python                  : Completes based on the contents of the current Python environment, the Python
                          built-ins, and xonsh operators.
path                    : Completes path names.

And micromamba shell hook -s xonsh gives:

# Copyright (C) 2012 Anaconda, Inc
# SPDX-License-Identifier: BSD-3-Clause
# Much of this forked from https://github.com/gforsyth/xonda
# Copyright (c) 2016, Gil Forsyth, All rights reserved.
# Original code licensed under BSD-3-Clause.

try:
    # xonsh >= 0.18.0
    from xonsh.lib.lazyasd import lazyobject
except:
    # xonsh < 0.18.0
    from xonsh.lazyasd import lazyobject

from xonsh.completers import completer
from xonsh.completers.tools import complete_from_sub_proc, contextual_command_completer

_REACTIVATE_COMMANDS = ('install', 'update', 'upgrade', 'remove', 'uninstall')


def _parse_args(args=None):
    from argparse import ArgumentParser
    p = ArgumentParser(add_help=False)
    p.add_argument('command')
    ns, _ = p.parse_known_args(args)
    if ns.command == 'activate':
        p.add_argument('env_name_or_prefix', default='base')
    elif ns.command in _REACTIVATE_COMMANDS:
        p.add_argument('-n', '--name')
        p.add_argument('-p', '--prefix')
    parsed_args, _ = p.parse_known_args(args)
    return parsed_args


def _raise_pipeline_error(pipeline):
    stdout = pipeline.out
    stderr = pipeline.err
    if pipeline.returncode != 0:
        message = ("exited with %s\nstdout: %s\nstderr: %s\n"
                   "" % (pipeline.returncode, stdout, stderr))
        raise RuntimeError(message)
    return stdout.strip()


def _mamba_activate_handler(env_name_or_prefix=None):
    if env_name_or_prefix == 'base' or not env_name_or_prefix:
        env_name_or_prefix = $MAMBA_ROOT_PREFIX
    __xonsh__.execer.exec($(/usr/bin/micromamba shell activate -s xonsh -p @(env_name_or_prefix)),
                          glbs=__xonsh__.ctx,
                          filename="$(/usr/bin/micromamba shell activate -s xonsh -p " + env_name_or_prefix + ")")


def _mamba_deactivate_handler():
    __xonsh__.execer.exec($(/usr/bin/micromamba shell deactivate -s xonsh),
                          glbs=__xonsh__.ctx,
                          filename="$(/usr/bin/micromamba shell deactivate -s xonsh)")


def _mamba_passthrough_handler(args):
    pipeline = ![/usr/bin/micromamba @(args)]
    _raise_pipeline_error(pipeline)


def _mamba_reactivate_handler(args, name_or_prefix_given):
    pipeline = ![/usr/bin/micromamba @(args)]
    _raise_pipeline_error(pipeline)
    if not name_or_prefix_given:
        __xonsh__.execer.exec($(/usr/bin/micromamba shell reactivate -s xonsh),
                              glbs=__xonsh__.ctx,
                              filename="$(/usr/bin/micromamba shell -s xonsh reactivate)")


def _micromamba_main(args=None):
    parsed_args = _parse_args(args)
    if parsed_args.command == 'activate':
        _mamba_activate_handler(parsed_args.env_name_or_prefix)
    elif parsed_args.command == 'deactivate':
        _mamba_deactivate_handler()
    elif parsed_args.command in _REACTIVATE_COMMANDS:
        name_or_prefix_given = bool(parsed_args.name or parsed_args.prefix)
        _mamba_reactivate_handler(args, name_or_prefix_given)
    else:
        _mamba_passthrough_handler(args)


if 'CONDA_SHLVL' not in ${...}:
    $CONDA_SHLVL = '0'
    import os as _os
    import sys as _sys
    _sys.path.insert(0, _os.path.join($MAMBA_ROOT_PREFIX, "condabin"))
    del _os, _sys


aliases['micromamba'] = _micromamba_main


@contextual_command_completer
def _micromamba_proc_completer(ctx):
    if not ctx.args:
        return

    return (
        complete_from_sub_proc(
            "micromamba",
            "completer",
            *[a.value for a in ctx.args[1:]],
            ctx.prefix,
            sep=lambda x: x.split()
        ),
        False,
    )

completer.add_one_completer("micromamba", _micromamba_proc_completer, "<bash")

Please let me know if I can provide anything additional to help reproduce this!

dotsdl avatar Jan 08 '25 00:01 dotsdl

I can confirm the issue - wrong completion - the list of completions is for mamba instead of a right tool:

image

It's needed to check where is the issue: in downstream mamba code (_micromamba_proc_completer) or in xonsh completion (complete_from_sub_proc).

anki-code avatar Jan 08 '25 09:01 anki-code

Thanks @anki-code! Any advice on a workaround?

dotsdl avatar Feb 13 '25 21:02 dotsdl

I think you need to fix micromamba completer:

    if not ctx.args:
        return

like this (the similar in conda):

      if not ctx.args or ctx.args[0].value != 'micromamba':
          return

anki-code avatar Feb 14 '25 09:02 anki-code

I'm going to close this as downstream issue.

anki-code avatar Feb 14 '25 09:02 anki-code

Brilliant, thanks @anki-code! I'll create a PR in the downstream to fix this!

dotsdl avatar Feb 15 '25 00:02 dotsdl

PR is here, for reference: https://github.com/mamba-org/mamba/pull/3825

dotsdl avatar Feb 15 '25 00:02 dotsdl