Source code for xonsh.completers.bash

"""Xonsh hooks into bash completions."""

import xonsh.platform as xp
import xonsh.tools as xt
from xonsh.built_ins import XSH
from xonsh.completers.bash_completion import bash_completions
from xonsh.completers.tools import RichCompletion, contextual_command_completer
from xonsh.parsers.completion_context import CommandContext


[docs] @contextual_command_completer def complete_from_bash(context: CommandContext): """Completes based on results from BASH completion.""" env = XSH.env.detype() # type: ignore paths = XSH.env.get("BASH_COMPLETIONS", ()) # type: ignore command = xp.bash_command() args = [arg.value for arg in context.args] prefix = context.prefix # without the quotes args.insert(context.arg_index, prefix) line = " ".join(args) # lengths of all args + joining spaces begidx = sum(len(a) for a in args[: context.arg_index]) + context.arg_index endidx = begidx + len(prefix) opening_quote = context.opening_quote closing_quote = context.closing_quote if closing_quote and not context.is_after_closing_quote: # there already are closing quotes after our cursor, don't complete new ones (i.e. `ls "/pro<TAB>"`) closing_quote = "" elif opening_quote and not closing_quote: # get the proper closing quote closing_quote = xt.RE_STRING_START.sub("", opening_quote) comps, lprefix = bash_completions( prefix, line, begidx, endidx, env=env, paths=paths, command=command, line_args=args, opening_quote=opening_quote, closing_quote=closing_quote, arg_index=context.arg_index, ) def enrich_comps(comp: str): append_space = False if comp.endswith(" "): append_space = True comp = comp.rstrip() # ``bash_completions`` may have added closing quotes: return RichCompletion( comp, append_closing_quote=False, append_space=append_space ) comps = set(map(enrich_comps, comps)) if lprefix == len(prefix): lprefix += len(context.opening_quote) if context.is_after_closing_quote: # since bash doesn't see the closing quote, we need to add its length to lprefix lprefix += len(context.closing_quote) return comps, lprefix