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

Support for not inserting spaces after periods and such #7832

Open
rainerschoe opened this issue Mar 17, 2021 · 3 comments
Open

Support for not inserting spaces after periods and such #7832

rainerschoe opened this issue Mar 17, 2021 · 3 comments

Comments

@rainerschoe
Copy link

rainerschoe commented Mar 17, 2021

fish, version 3.1.2 on rxvt-unicode-256color

Hi,
What we are doing:
We are developing an open-source CLI application called gWhisper, which has a dynamic and complex kind of CLI argument grammar.

To provide TAB completions we provide a way to get a list of completions, by calling the tool with the added --complete=fish flag.

We feed this list to fish by using the command substitution feature of complete -a like so:

function _gwhisper_getCompletions;
  ... code to extract args from prompt ...
  set -l cmd "$commandName --complete=fish \"$args\""
  set -l completions (eval $cmd)
  for completion in $completions
    echo $completion
  end
end

complete -f -c gwhisper -a '(_gwhisper_getCompletions)'

What already works:
This works mostly fine as you can see in this recording:
example

Where we ran into problems:
However we noticed some strange behavior, as fish is doing heavy post processing on the given list of completions.
It boils down to two things:

  1. fish adding a whitespace when a completion suggestion is selected, based on the last char in the suggestion.
  2. Our grammar not being able to give suggestions until the next whitespace in one go, because:
    • Too many possibilities in some cases, as deep nesting is possible until we reach next whitespace (>1000)
    • We use in some cases other delimiters than whitesspace. e.g. . to separate namespaces, which leads to long choice-trees until the next whitespace is reached.

Example:
User wants to type: house.bedroom.bed.pillow.operations wash temperature=60
think of user pressing <TAB> after typing hous

There are just too many choices to select after the house namespace to complete until next expected space, so our grammar look-ahead will complete until next nesting step, which is the room.

The resulting list of suggestions which are passed to fish looks like this (excluding documentation):

house.bedroom.
house.livingroom.
house.kitchen.

If one of them is selected however, fish will post-process this and complete:
house.bedroom. (with trailing space)
This breaks everything, since our parser is not expecting a space here.

We noticed, that if a completion does end with some special characters like = or : no space is added. This saves us some trouble, as in most cases this is by chance the point where our look-ahead algorithm stops with suggestions, but not in all cases as in the above example.

What we are looking for:
We would like to have a way to disable the fish post-processing completely, allowing us to specify when a space should be completed by just adding a space into the candidate string.
NOTE: currently spaces in candidates are also post processed and are escaped, which is an other issue and should also be disabled in this "raw mode".

Alternatively it would be nice to configure the fish completion behavior in more detail (I.e. giving more control over characters after which space is added or not).

We read the complete manpage multiple times, but could not find a way to achieve the desired behavior 😭

Is there any other API to inject more "raw"-style dynamic completion lists?

@zanchey
Copy link
Member

zanchey commented Mar 18, 2021

Is there any other API to inject more "raw"-style dynamic completion lists?

Not at this stage. You will be pleased to know that this was changed somewhat in #6928 (included in 3.2.0 and above) to not insert a space straight after periods. There is further discussion of customisability in that issue.

@rainerschoe
Copy link
Author

rainerschoe commented Mar 18, 2021

OK, thank you for the reply. It is good to hear, that there is some awareness about the problem.

Not adding a space after period will help in this special case only, but will not solve the general problem, as our dynamic grammar may branch on arbitrary characters and it is not always easy to say on which.

Ideal solution would be a kind of "raw" mode for completions, disabling all fish post-processing (space adding and maybe also escaping), providing a way to exolicitly add space (if no escaping is done, this could be done just by adding a space in the suggestion 😄 ).

@krobelus
Copy link
Member

krobelus commented Mar 18, 2021

One option is to not use the completion pager. The fzf integration does that; it probably uses commandline --replace --current-token.
Maybe your use case is something that can fully be solved by an external tool that implements a configurable pager?

I think there are few real-world cases where our hardcoded punctuation rules don't work, but maybe that's just a chicken-and-egg problem?
BTW, the Cobra project wants to do the same, some (fairly noisy) discussion here.

If we were to implement this, there are several options for the interface:

  1. Adding an option to complete is the most obvious solution. That would currently break for wrapper commands (sudo your-command <TAB>) because completions are serialized to text.
  2. Adding metadata to individual completion results is unlikely to be an option, because it would make the serialization format more complex.
  3. Adding a global option to control this behavior for all completions seems hacky. Clients would need to enable/disable it temporarily

Ideal solution would be a kind of "raw" mode for completions, disabling all fish post-processing (space adding and maybe also escaping),

That sounds reasonable, the "wrapper command" issue might be a concern though.

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

No branches or pull requests

3 participants