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

use shtab for shell autocompletion #108

Closed
tshu-w opened this issue Dec 1, 2021 · 9 comments
Closed

use shtab for shell autocompletion #108

tshu-w opened this issue Dec 1, 2021 · 9 comments
Labels
question Further information is requested

Comments

@tshu-w
Copy link
Contributor

tshu-w commented Dec 1, 2021

Hi, I found argcomplete is slow and doesn't work well with zsh. Could you consider use shtab for shell completition.

@mauvilsa
Copy link
Member

mauvilsa commented Dec 3, 2021

It is true that the current autocompletion is not as good as I would like it. In fact without considering speed or different shells support, it does not work for advanced features such as the subclasses.

Though just because shtab says that it is faster, it does not mean that if used in jsonargparse it will be as fast as you expect for a particular use case. This highly depends on how shtab works internally and it wasn't easy for me to figure out with a quick look at the source code. Being more specific take for example the LightningCLI use case. A rather complex parser is automatically created from the type hint annotations of several classes. This requires to import libraries such as pytorch which takes a while. If this import is needed every time the user presses TAB then the response will be slow every time. For this to be fast it would need to be that in the first TAB a daemon process is started to take care of the first and subsequent TAB completions (slow for the first TAB and fast after that). Then this daemon would kill itself after a period of inactivity. I don't think shtab works this way though I could be wrong.

Another issue is that shtab seems to be very argparse specific and probably will not work well with extensions such as jsonargparse. And there doesn't seem to be support for custom completion logic iterative/shtab#34. This is necessary to support the advanced features such as subclasses and type hints, see typehints.py#L359-L379.

@mauvilsa mauvilsa added the question Further information is requested label Dec 3, 2021
@tshu-w
Copy link
Contributor Author

tshu-w commented Dec 3, 2021

Though just because shtab says that it is faster, it does not mean that if used in jsonargparse it will be as fast as you expect for a particular use case.

shtab works in a different way than autocompletion. It generates shell completion functions directly for the user and user should move the functions to fpath. Once the completing functions was generated, the complementary stuff is done through the shell. I just use it with LightningCLI. I modified the parser like here and I can generate _run with run -s zsh | tee $XDG_DATA_HOME/zsh/site-functions/_run. It's immediately and I'm really happy with it.

Screen Shot 2021-12-03 at 16 29 24

And there doesn't seem to be support for custom completion logic iterative/shtab#34.

Yes, it partly can. See the examples they provide.


Overall I think the completion needs to be done on the shell side rather than the python side because there will be complex parsers like LightningCLI and then it's hard to guarantee performance and generality.

@tshu-w
Copy link
Contributor Author

tshu-w commented Dec 3, 2021

I have also arise a disscusion here Lightning-AI/pytorch-lightning#10858

@mauvilsa
Copy link
Member

mauvilsa commented Dec 3, 2021

lit_cli.py#L97

shtab.add_argument_to(self.parser, ["-s", "--print-completion"])

Interesting. But then shtab seems to work nicely already? In the context of this github issue are you proposing anything specific to do in jsonargparse?

@tshu-w
Copy link
Contributor Author

tshu-w commented Dec 3, 2021

Interesting. But then shtab seems to work nicely already? In the context of this github issue are you proposing anything specific to do in jsonargparse?

Yes, I think jsonargparse can be integrated it by default or through options. Or easy for jsonargparse to add subclasses and type hints. I am not really familiar with jsonargparse or shitab and am not sure where this should be done or downstream like LightningCLI. As a PytorchLightning user I'm just sharing my findings to see if there's anything you can enhance jsonargparse with shitab 😄

@casperdcl
Copy link

casperdcl commented Dec 6, 2021

Yes should be fine... Just one line from https://docs.iterative.ai/shtab/use/#library-usage should suffice:

shtab.add_argument_to(parser, ["-s", "--print-completion"])

Just to confirm:

  • shtab only requires an argparse.ArgumentParser-like object for it to generate completions
  • shtab is indeed faster than argcomplete as it generates shell completions in advance rather than at each TAB by default
  • should dynamic completions be required (i.e. you need to re-compute completions on pressing TAB) you can do so for individual arguments using custom completions, e.g. https://github.com/iterative/shtab/blob/master/examples/customcomplete.py effectively does ls *.txt but you could do some_python_command --list-options instead.

@tshu-w
Copy link
Contributor Author

tshu-w commented Feb 22, 2022

@mauvilsa Hi, I found something should be down in jsonargparse:

shtab use option type to decide completion nargs format in this line, however ActionConfigFile doesn't inherit from any of OPTION_MULTI = _AppendAction, _AppendConstAction, _CountAction, should ActionConfigFile inherit from _AppendAction as it accept python cli.py --config config.yaml --confg config2.yaml?

@mauvilsa
Copy link
Member

mauvilsa commented Mar 3, 2022

I have created two issues in the shtab repo which summarize what is needed for jsonargparse to implement the same features when used with shtab as with argcomplete. These are:

@mauvilsa
Copy link
Member

In jsonargparse v4.30.0 now there is an experimental native shtab support. See the docs. I have only tried it with bash so not sure how well it works in other shells. Also I haven't tested it much with LightningCLI but in principle it should work. Any feedback is welcome.

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

No branches or pull requests

3 participants