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

[bash] Update the completion setting after _completion_loader #3667

Merged
merged 2 commits into from
Mar 10, 2024

Conversation

akinomyoga
Copy link
Contributor

@akinomyoga akinomyoga commented Mar 10, 2024

Original problem

This is a fix for an issue reported at scop/bash-completion#1123. The original problem is that the fzf completion setting does not fully preserve the completion settings of cd set by bash-completion-2.12. More specifically, bash-completion completes also variable names through the -v option of complete when shopt -s autocd shopt -s cdable_vars is specified, but the -v option is lost for bash-completion 2.12 when Fzf's completion setting is present. See the original thread for the details.

Description of the problem

The problem is that when the completion setting is loaded by _fzf_handle_dynamic_completion using bash-completion's _completion_loader, only the function specified by -F is used by fzf. The completion settings specified by other complete options are ignored.

The problem does not arise when the completion setting already exists when Fzf's completion.bash is loaded or when _fzf_setup_completion is called. This is because __fzf_defc preserves the other complete options. The reason that the problem was not observed with bash-completion 2.11 is that bash-completion 2.12 started to load the completion setting of cd dynamically.

Solution

When the completion settings are loaded using _completion_loader, the other complete options should be applied to the completion setting in the same way as __fzf_defc does.

The main fix is in commit c732298.

Associated refactoring

To reuse existing codes, there is a refactoring commit (0214e50) before the main commit. In the current codebase, for the original completion settings, the pieces of the codes to determine the variable name and access the stored data are scattered. In this commit, we define functions to access these variables. The functions are used in the main fix of this PR.

This refactoring also resolves an inconsistent escaping of $cmd: $cmd is escaped as ${...//[^A-Za-z0-9_]/_} in some places, but it is escaped as ${...//[^A-Za-z0-9_=]/_} in some other places. The latter leaves the character = in the command name, which causes an issue because = cannot be a part of a variable name. For example, the following test case produces an error message:

$ COMP_WORDBREAKS=${COMP_WORDBREAKS//=}
$ _test1() { COMPREPLY=(); }
$ complete -vF _test1 cmd.v=1.0
$ _fzf_setup_completion path cmd.v=1.0
$ cmd.v=1.0 [TAB]
bash: _fzf_orig_completion_cmd_v=1_0: invalid variable name

The behavior of leaving = was present from the beginning when saving the original completion is introduced in commit 9140151, and this does not seem to have specific reasoning. We replace = as well as the other non-identifier characters.

Note: In the new functions, the variable REPLY is used to return values. This design is to make it useful with the value substitutions, which is a new Bash feature of the next release 5.3, and was originally the feature introduced by mksh.

In the current codebase, for the original completion settings, the
pieces of the codes to determine the variable name and to access the
stored data are scattered.  In this patch, we define functions to
access these variables.  Those functions will be used in a coming
patch.

* This patch also resolves an inconsistent escaping of "$cmd": $cmd is
  escaped as ${...//[^A-Za-z0-9_]/_} in some places, but it is escaped
  as ${...//[^A-Za-z0-9_=]/_} in some other places.  The latter leaves
  the character "=" in the command name, which causes an issue because
  "=" cannot be a part of a variable name.  For example, the following
  test case produces an error message:

  $ COMP_WORDBREAKS=${COMP_WORDBREAKS//=}
  $ _test1() { COMPREPLY=(); }
  $ complete -vF _test1 cmd.v=1.0
  $ _fzf_setup_completion path cmd.v=1.0
  $ cmd.v=1.0 [TAB]
  bash: _fzf_orig_completion_cmd_v=1_0: invalid variable name

  The behavior of leaving "=" was present from the beginning when
  saving the original completion is introduced in commit 9140151, and
  this does not seem to be a specific reasoning.  In this patch, we
  replace "=" as well as the other non-identifier characters.

* Note: In this patch, the variable REPLY is used to return values
  from functions.  This design is to make it useful with the value
  substitutions, a new Bash feature of the next release 5.3, which is
  taken from mksh.
@junegunn
Copy link
Owner

Thanks for the excellent analysis and the patch! 👍

@junegunn junegunn merged commit 01871ea into junegunn:master Mar 10, 2024
5 checks passed
@akinomyoga akinomyoga deleted the update-orig_complete branch March 10, 2024 18:40
@akinomyoga
Copy link
Contributor Author

Thank you!

@junegunn junegunn mentioned this pull request Mar 12, 2024
10 tasks
@gautaz gautaz mentioned this pull request Sep 20, 2024
10 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants