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

fix(zsh): Fix variable completion #697

Merged
merged 12 commits into from Oct 18, 2020
Merged

Conversation

heyrict
Copy link
Contributor

@heyrict heyrict commented Oct 9, 2020

This PR contains the following fixes:

  • Allow completion of variables in the command context
  • Allow completion of variables after --set flag

Closes #695

@casey
Copy link
Owner

casey commented Oct 9, 2020

Awesome! I found a couple issues:

This shows variables, but the "variables" header is at the top of the output, not above the variables:

just <TAB> 

Screen Shot 2020-10-09 at 16 30 11

This completes VARIABLE_NAME:

just --set V<TAB> 

But it adds a = after VARIABLE_NAME, but = is only used for the just VARIABLE_NAME=value shorthand, not the --set form, which uses just --set VARIABLE_NAME value.

This produces an error:

just --set VALUE foo <TAB>

Screen Shot 2020-10-09 at 16 33 58

It looks like perhaps 'foo' isn't being passed to the underlying invocation?

@casey
Copy link
Owner

casey commented Oct 9, 2020

The tests were failing because a new version of clippy introduced a new lint, and because the generated completion scripts were behind the code in subcommands.rs. I pushed diffs that fix both errors.

@heyrict
Copy link
Contributor Author

heyrict commented Oct 10, 2020

But it adds a = after VARIABLE_NAME, but = is only used for the just VARIABLE_NAME=value shorthand, not the --set form, which uses just --set VARIABLE_NAME value

By convention, one argument can be followed by at most one flag asaik. It's out of my knowledge to pass two argument to one flag. I can remove the completion part of --set option if you think it is not suitable here.

This shows variables, but the "variables" header is at the top of the output, not above the variables

Can I have a look at your zshrc?

I pushed diffs that fix both errors.

Thanks :)

@casey
Copy link
Owner

casey commented Oct 10, 2020

By convention, one argument can be followed by at most one flag asaik. It's out of my knowledge to pass two argument to one flag. I can remove the completion part of --set option if you think it is not suitable here.

Ah, okay. I think in that case it's probably better not to try to complete --set in that case.

Can I have a look at your zshrc?

Yup, it's here: https://github.com/casey/local/blob/master/etc/zshrc

It refers to other files, which are also in that repo, and I think they're all in this folder: https://github.com/casey/local/tree/master/etc/zsh

@heyrict
Copy link
Contributor Author

heyrict commented Oct 12, 2020

Thanks :)

This shows variables, but the "variables" header is at the top of the output, not above the variables

This issue doesn't exist on my side. I'll have a look at your code once I have time.

@casey
Copy link
Owner

casey commented Oct 12, 2020

This issue doesn't exist on my side. I'll have a look at your code once I have time.

Hmm, interesting. I don't want to hold up this diff because of a problem that might only be on my end.

I pushed a diff that makes the test pass, but when testing locally I ran into the following issue:

just --set V<TAB>

Completes to:

just --set VARIABLE_NAME=

The = can only be used with sets of the form just VARIABLE_NAME=value, and not --set VARIABLE_NAME value, which doesn't take a =. I tried having a look at the code to see if I could fix this myself, but I have absolutely no idea how zsh completion scripts work 😅

@casey
Copy link
Owner

casey commented Oct 12, 2020

I noticed that this PR introduces a numargs variable, that maps flags to the number of arguments they take. Will this have to be kept in sync with new flags, and what will happen if a new flag is added that takes arguments, but this map isn't updated?

@heyrict
Copy link
Contributor Author

heyrict commented Oct 13, 2020

I noticed that this PR introduces a numargs variable, that maps flags to the number of arguments they take. Will this have to be kept in sync with new flags, and what will happen if a new flag is added that takes arguments, but this map isn't updated?

I'm afraid not. Probably checking the first argument that matches the name of an existing recipe should work if you'd like to avoid the args checking hack. I'll try that once I have time.

@casey
Copy link
Owner

casey commented Oct 13, 2020

I'm afraid not. Probably checking the first argument that matches the name of an existing recipe should work if you'd like to avoid the args checking hack. I'll try that once I have time.

That would be great. My expectation is that I'll forget to update this script when I add new command line options. If the completion script has fewer features, like not completing certain things that it could, I think that worth it if it doesn't get out of date.

@kenden
Copy link
Contributor

kenden commented Oct 16, 2020

Hi @casey, about:

The = can only be used with sets of the form just VARIABLE_NAME=value, and not --set VARIABLE_NAME value, which doesn't take a =.

Do you think just could be changed to allow a space and a = when using --set?
i.e. to have both '--set VARIABLE_NAME value' and '--set VARIABLE_NAME=value' be valid syntax.
It seems pretty common for other commands to allow both.
And doing this should allow completing the variable name too?

@casey
Copy link
Owner

casey commented Oct 16, 2020

This is definitely a good idea, but I don't think it can be implemented without undesirable side-effects with the argument parser, clap, that Just uses.

When I set the "value delimiter" for --set to =, this does work as you'd expect --set foo=bar. However, it will error if you do --set foo=bar=baz, i.e. if you use = in the value that you're trying to set. I think this would be undesirable, since it would mean that setting variables would fail if the value happened to contain a =.

(The reason it fails is because it interprets foo=bar=baz as three arguments to --set, which is like if you did --set foo bar --set baz, the second set only has the key and no value.)

@casey
Copy link
Owner

casey commented Oct 17, 2020

I think this has an issue, if any flags or variables are given, recipe name tab completion doesn't work, and it instead shows the usage string for the first recipe:

$ just JUST_LOG=bar <TAB>
# add git log messages to changelog
changes:
    git log --pretty=format: >> CHANGELOG.md

@heyrict
Copy link
Contributor Author

heyrict commented Oct 18, 2020

It seems that I've accidentally removed one line from the source code. It should be fine now.

@casey
Copy link
Owner

casey commented Oct 18, 2020

It looks like there's some state that's persisting between calls to the completion script.

$ just JUST_LOG=foo <TAB> # shows recipes and variables
$ just JUST_LOG=foo chang<TAB> # completes to `changes`
$ just JUST_LOG=foo <TAB> # now shows the text of the `changes recipe`

@heyrict
Copy link
Contributor Author

heyrict commented Oct 18, 2020

It looks like there's some state that's persisting between calls to the completion script.

Thanks for the effort on debugging. Fixed now.

@casey casey merged commit 0e1af65 into casey:master Oct 18, 2020
@casey
Copy link
Owner

casey commented Oct 18, 2020

Awesome, looks good!

@heyrict heyrict deleted the zsh-variable-completion branch October 18, 2020 05:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

zsh autocomplete issue tabbing after passing --set VAR value
3 participants