adaszko / complgen

Declarative bash/fish/zsh completions without writing shell scripts
Apache License 2.0
221 stars 7 forks source link

[FR] Add support for option arguments using = #18

Closed Drugoy closed 1 year ago

Drugoy commented 1 year ago

I've seen this in the description of the project:

Passing option arguments using = is not currently supported. E.g. --foo=bar doesn't work, but --foo bar does.

Is there a way to workaround this limitation? Unfortunately, psql's option service works only that way and there are no synonymous options that don't require the =.

p.s.: if the limitation is too hard to work around and you don't plan to add it - it'd be sad, of course, but feel free to close this ticket then.

adaszko commented 1 year ago

Is there a way to workaround this limitation?

One thing that comes to my mind is to use a { … } command to generate possible completions that bake in the --service= prefix, so something like <SVC> ::= { sed -n 's/^\s*\[\(.*\)\]/\1/p' ~/.pg_service.conf | sed ‘s/^/--service=/‘ };.

Drugoy commented 1 year ago

psql.usage


<OPTION> ::= service\=<SVC>
        | --host
        | --port <PORT>
        | --dbname
        ;

<SVC> ::= { sed -n 's/^\s*\[\(.*\)\]/\1/p' ~/.pg_service.conf | sed 's/^/service=/' };
<PORT> ::= 5432;

produces this error on compilation attempt:

Error: Parsing error: "<OPTION> ::= service\\=<SVC>\n\t| --host\n\t| --port <PORT>\n\t| --dbname\n\t;\n\n<SVC> ::= { sed -n 's/^\\s*\\[\\(.*\\)\\]/\\1/p' ~/.pg_service.conf | sed 's/^/service=/' };\n<PORT> ::= 5432;\n"

p.s.: there's really no need for chaining seds, 1 sed is enough (it produces the same result, but as well fails to compile):

<SVC> ::= { sed -n 's/^\s*\[\(.*\)\]/service=\1/p' ~/.pg_service.conf };

p.p.s.: please note, that unlike all/most other named args, service goes without -- prefix.

adaszko commented 1 year ago

Replace service\=<SVC> with just <SVC>:

psql [<OPTION>];                                                                                                                                                                                        

<OPTION> ::= <SVC>
        | --host
        | --port <PORT>
        | --dbname
        ;

<SVC> ::= { sed -n 's/^\s*\[\(.*\)\]/\1/p' ~/.pg_service.conf | sed 's/^/service=/' };
<PORT> ::= 5432;
Drugoy commented 1 year ago

Oh, but then psql <tab> will suggest both named args (--dbname, --host, --port) and all the possible services in a single list, mixing named args and values for a specific named arg... This is too sub-optimal for me, to the point that I'd rather prefer having to manually add = for now (until you, hopefully, add this feature properly). But thanks for a possible way out (it is ~acceptable if the list of services isn't really big)!

adaszko commented 1 year ago

Hi again! I just pushed an implementation of a mechanism that I call subword matching. It should make your grammar:

psql [<OPTION>];

<OPTION> ::= service=<SVC>
        | --host
        | --port <PORT>
        | --dbname
        ;

<SVC> ::= { sed -n 's/^\s*\[\(.*\)\]/\1/p' pg_service.conf };
<PORT> ::= 5432;

just work, basically. Let me know if you come across any bugs!

Drugoy commented 1 year ago

This is so awesome! It seems to work fine! I will try to use your util more quite soon for other utils where I miss such completion suggestions that can be achieved with this quite simple syntax! Thank you!

edit: tested a bit more and noticed that while service= now works fine - chaining multiple ---prefixed args now fails: psql --host a {TAB} doesn't produce suggestions anymore (service=, --port and --dbname were expected to be suggested here).

Drugoy commented 1 year ago

@adaszko should I file this in a new ticket or would you rather reopen this one and revert related changes until a better fix?

adaszko commented 1 year ago

@adaszko should I file this in a new ticket or would you rather reopen this one and revert related changes until a better fix?

It's does what the grammar says. You need <OPTION>... for it to be completed more than once.