Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bash completion: command not found #1595

Closed
blahgeek opened this issue Aug 20, 2016 · 5 comments · Fixed by #1602
Closed

Bash completion: command not found #1595

blahgeek opened this issue Aug 20, 2016 · 5 comments · Fixed by #1602
Labels

Comments

@blahgeek
Copy link
Contributor

I'm using xonsh 0.4.5 on OS X, with bash-completion 1.3 installed with homebrew.

My $BASH_COMPLETIONS is set to ['/usr/local/etc/bash_completion'], but bash completion does not working. So I looked at the code at completers/bash.py and tested the following code:

bash -c 'source "/usr/local/etc/bash_completion.d/ssh"\nCOMP_WORDS=(ssh M)\nCOMP_LINE=\'ssh M\'\nCOMP_POINT=${#COMP_LINE}\nCOMP_COUNT=6\nCOMP_CWORD=1\n_ssh ssh M ssh\nfor ((i=0;i<${#COMPREPLY[*]};i++)) do echo ${COMPREPLY[i]}; done\n'
/usr/local/etc/bash_completion.d/ssh: line 3: have: command not found
/bin/bash: line 6: _ssh: command not found

The have command in bash_completion.d/ssh is defined in bash_completion which is not loaded. I also checked bash-completion 2.3.5 in archlinux, its completions/ssh also uses some functions like _init_completion in bash_completion.

I have source /usr/local/etc/bash_completion in my .bashrc but it wont load while running bash by bash -c.

Did I do anything wrong or it may be a bug? Thanks!

@scopatz scopatz added the bug label Aug 21, 2016
@scopatz scopatz added this to the v0.5 milestone Aug 21, 2016
@scopatz
Copy link
Member

scopatz commented Aug 21, 2016

I don't think that you are doing anything wrong. I think it is just that you completions may be out of date. If I look at the defintion of have() on my Ubuntu box, I see:

# Backwards compatibility for compat completions that use have().
# @deprecated should no longer be used; generally not needed with dynamically
#             loaded completions, and _have is suitable for runtime use.
have()
{
    unset -v have
    _have $1 && have=yes
}

However, we could modify our bash completer to also source the /usr/local/etc/bash_completion first too. Basically, we'd look for a bash_completion file in the corresponding directory and that to the source command. Would you be willing to take a stab at that @blahgeek?

@blahgeek
Copy link
Contributor Author

Thanks for your reply~

Yes the completions installed by homebrew is a little bit outdated. But still, if I ran that command on my linux box (with bash-completion 2.3.5 installed), it prints:

/usr/share/bash-completion/completions/ssh: line 158: _init_completion: command not found

It seems that, one way or another, individual completion scripts will depend on the "main" script bash_completion.

I thought about fixing this issue by sourcing the bash_completion first in complete_from_bash function, but then I realized that may not be a good idea, since bash_completion loads all scripts under bash_completion.d and can take quite a while.

A good way to fix this can be modifying complete_from_bash to maintain a long-running background bash process, so it only loads all the scripts at startup and we can use pipes to get completions from it. Though it will need a almost complete rewrite of completers/bash.py.

Any ideas? @scopatz

@scopatz
Copy link
Member

scopatz commented Aug 21, 2016

bash_completion loads all scripts under bash_completion.d and can take quite a while

Yeah, how slow is it though really? Do you have any timings?

A good way to fix this can be modifying complete_from_bash to maintain a long-running background bash process, so it only loads all the scripts at startup and we can use pipes to get completions from it. Though it will need a almost complete rewrite of completers/bash.py

I think that this would be too fragile, personally. It also seems excessive for their to be a bash process open for every xonsh process in practice.

If loading all the scripts really is too slow (and I can see how it would be), I think a better strategy would be:

  1. the first time we load all the completers via bash_completion, we also grab the source code for all of the bash functions in the bash_completion file. Bash does make this relatively easy to do. We store these in some internal cache.
  2. When a completer is executed, we glue the function definitions from bash_completion into the script we are going to run prior to the `source "completer/file.sh" call.

This would make sure that those functions are available. Alternatively, we could

  1. have an internal copy of bash_completion with just the function defs that xonsh always prepends, or
  2. figure out a ways to dynamically comment out the completer loading in bash_completion prior to sourcing it directly.

I'd be pretty happy with an implementation of any of the above strategies.

@blahgeek
Copy link
Contributor Author

How about that?

I set BASH_COMPLETION_DIR and BASH_COMPLETION_COMPAT_DIR to prevent bash_completion to loading every scripts in completions.d

@scopatz
Copy link
Member

scopatz commented Aug 21, 2016

I set BASH_COMPLETION_DIR and BASH_COMPLETION_COMPAT_DIR to prevent bash_completion to loading every scripts in completions.d

Awesome!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants