"""Xonsh hooks into bash completions."""importxonsh.platformasxpimportxonsh.toolsasxtfromxonsh.built_insimportXSHfromxonsh.completers.bash_completionimportbash_completionsfromxonsh.completers.toolsimportRichCompletion,contextual_command_completerfromxonsh.parsers.completion_contextimportCommandContext
[docs]@contextual_command_completerdefcomplete_from_bash(context:CommandContext):"""Completes based on results from BASH completion."""env=XSH.env.detype()# type: ignorepaths=XSH.env.get("BASH_COMPLETIONS",())# type: ignorecommand=xp.bash_command()args=[arg.valueforargincontext.args]prefix=context.prefix# without the quotesargs.insert(context.arg_index,prefix)line=" ".join(args)# lengths of all args + joining spacesbegidx=sum(len(a)forainargs[:context.arg_index])+context.arg_indexendidx=begidx+len(prefix)opening_quote=context.opening_quoteclosing_quote=context.closing_quoteifclosing_quoteandnotcontext.is_after_closing_quote:# there already are closing quotes after our cursor, don't complete new ones (i.e. `ls "/pro<TAB>"`)closing_quote=""elifopening_quoteandnotclosing_quote:# get the proper closing quoteclosing_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,)defenrich_comps(comp:str):append_space=Falseifcomp.endswith(" "):append_space=Truecomp=comp.rstrip()# ``bash_completions`` may have added closing quotes:returnRichCompletion(comp,append_closing_quote=False,append_space=append_space)comps=set(map(enrich_comps,comps))iflprefix==len(prefix):lprefix+=len(context.opening_quote)ifcontext.is_after_closing_quote:# since bash doesn't see the closing quote, we need to add its length to lprefixlprefix+=len(context.closing_quote)returncomps,lprefix