Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Append/replace convention for xfuncs #962

scop started this conversation in Ideas
May 7, 2023 · 2 comments · 6 replies
Discussion options

The xfuncs we currently have that operate on COMPREPLY have inconsistent behavior with regards to whether they append or replace to the target. Would be good to be consistent with this.

If we are to choose between always append or replace, I think I'd go with append, as it's easier to work around at call sites if replace semantics are preferred.

Then again, I suppose we could look into providing an -a option to _comp_xfunc for controlling this, but I'm not sure if that's worth the trouble.

You must be logged in to vote

Replies: 2 comments 6 replies

Comment options

I had a related idea, though I haven't thought deeply about whether it's really worth it: Maybe it is useful to provide a way to adjust the behavior through _comp_compgen also for exported functions that generate completions.

For example, when the _comp_compgen call has the following form (with a slash in 1ドル):

_comp_compgen [-aR|-v var|-c cur] CMD/NAME args...

it internally calls _comp_xfunc CMD compgen_NAME instead of _comp_compgen_NAME, where the xfunc is defined with the name _comp_xfunc_CMD_compgen_NAME.

You must be logged in to vote
2 replies
Comment options

In this way, one can implement _comp_xfunc_CMD_compgen_NAME using _comp_comgen and let the caller decide whether to replace or append. It replaces by default the same as the other _comp_compgen_NAME. If one wants to append the new completions, one can call it using _comp_compgen -a CMD/NAME args....

Comment options

scop May 7, 2023
Maintainer Author

Sounds good to me in principle, although the CMD/NAME syntax feels a bit magical. How about moving the xfunc cmd to [-x CMD]?

Comment options

So, exported generator functions have the name _comp_xfunc_CMD_compgen_NAME and are supposed to be called by _comp_compgen [-aR|-v var|-c cur] -x CMD NAME ....

  • Q. When there are no _comp_compgen options (-aR|-v var|-c cur), one might call them by _comp_compgen -x CMD NAME ... or _comp_xfunc CMD compgen_NAME. Which one is preferred? According to the decision in style(_comp_compgen): call _comp_compgen_filedir directly #964 (comment) , we would directly want to call _comp_xfunc CMD compgen_NAME, but I would like to make the xfunc generator case as an exception, i.e., use _comp_compgen -x CMD NAME ..., because it is more explicit that it is a generator call.

Also, it might be better to make a naming rule for the internal generator functions defined in specific completion files. I'd like to make use of _comp_compgen options also for the internal generator functions. Three options:

  1. Since we wouldn't use _comp_xfunc in this case and need to work with the function name _comp_compgen_*, private generator functions might be defined with the name _comp_compgen_compgen_cmd_CMD__NAME and are called by _comp_compgen [-aR|-v var|-c cur] cmd_CMD__NAME. But this makes another exception in the naming rule for private functions _comp_cmd_CMD__NAME.

  2. For the symmetry with the exported generator functions, another option is to define internal generator functions with the name _comp_cmd_CMD__compgen_NAME and call them by _comp_compgen [-aR|-v var|-c cur] -i CMD NAME ....

    Type Def Call
    exported generators _comp_xfunc_CMD_compgen_NAME _comp_compgen [-aR|-v var|-c cur] -x CMD NAME ...
    internal generators _comp_cmd_CMD__compgen_NAME _comp_compgen [-aR|-v var|-c cur] -i CMD NAME ...

    I thought -i could be alternatively -p (private), but private/public are both starting with p, and -x/-i looks better to me for the ex/in symmetry.

  3. Or call them by _comp_compgen [-aR|-v var|-c cur] -i NAME ... because CMD could be automatically extracted by ${BASH_SOURCE[1]##*/} as it is supposed to be called from the same file. But I think this could be too much simplification. It is confusing, so it's better to be explicit with CMD.

  4. Or any other ideas?

You must be logged in to vote
4 replies
Comment options

scop May 8, 2023
Maintainer Author

2 with -i looks best to me of the options so far. Given green field, -c would look even better (-x ~ xfunc, -c ~ cmd) but it's taken for cur already. Perhaps -m ~ cMd could be worth considering, but is quite far fetched.

In a sense I like 3 too, it would kind of make it clearer that it's really for the same cmd namespace and not to be used from anywhere else, but... dunno. Calling from somewhere else breaks immediately because there's no sourcing mechanism with it, so not that much of a problem.

Comment options

scop May 27, 2023
Maintainer Author

Thoughts on the above 2 vs 3 consideration? In particular, I'm wondering if the redundant CMD with -i is worth the symmetry.

Comment options

I realized that omitting CMD can be a problem when the completion is loaded through a symbolic link, in which case BASH_SOURCE will tell the path of the symbolic link. For this reason (in addition to the symmetry), I currently favor option 2.

We might still call readlink against "${BASH_SOURCE[1]}", but the implementation would become complicated and it requires spawning a process.

  • First, readlink is not standardized in POSIX. For this problem, we can extract the link target from the result of ls -l <file> instead of relying on readlink.
  • Even if readlink is available, we might need to resolve recursive links since readlink -f or realpath is not universally available. That said, we may not need to care about recursive links for completions/*.
  • To reduce the spawning cost, we might first check [[ -h ${BASH_SOURCE[1]} ]] before calling ls -l and only call ls -l when it is a symbolic link. For the second call of the same internal generator, we might create a delegating function _comp_cmd_LINK__compgen_NAME() { _comp_cmd_CMD__compgen_NAME "$@"; } on the fly.
  • Also, BASH_SOURCE[1] can contain a relative path to the file from the working directory when the file was loaded. We can make sure to use the absolute path in __load_completion.
Comment options

scop May 28, 2023
Maintainer Author

I agree, thanks for taking the time to explain 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
Ideas
Labels
None yet
2 participants

AltStyle によって変換されたページ (->オリジナル) /