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

feat(_comp_compgen_filedir,_comp_compgen_filedir_xspec): don’t suggest . and .. #1230

Merged
merged 2 commits into from
Nov 13, 2024

Conversation

Maelan
Copy link
Contributor

@Maelan Maelan commented Jul 2, 2024

This is a resurrection of #364, adapting to the current codebase, and addressing (I think) objections made there.

With this patch, file-and-directory completion provided by _comp_compgen_filedir and _comp_compgen_filedir_xspec do not suggest . nor .. nor */. nor */.. unless the user input is .. or */.. .

The condition can easily be changed from “unless the user has typed ..” to “unless there is only one suggestion” (just replace if [[ "${cur}" != @(..|*/..) ]] by if (( ${#toks[@]} > 1 )) ).

The motivation is to be able to tab-complete hidden files with more comfort: as hidden files are relatively rare, it is not uncommon to have no more than one hidden file in a given directory (or, in the case of a git repo, hidden files with a common prefix: .git, .gitignore…). It should then be enough to type just the dot and get the hidden file completed. Especially considering that typing a letter after a dot is uncomfortable, depending on your keyboard.

But . and .. are always there and get in the way of completion, despite being uninteresting suggestions: . alone can never get a slash appended, because it is always a prefix of the suggested .. ; and .. is strictly easier to type by pressing the dot key twice than by pressing the dot key, then whatever key is used to trigger completion.

There is one use case for suggesting .. though: in the previous PR, it was mentioned that some users may want to rely on completion to append a slash after they have typed .. ; so we must still suggest .. in some cases, which is what the “unless” condition addresses.

Another use case mentioned in the previous PR is that some users might(?) want to type . and expect bash-completion to complete it to .. ; this use case does not work with this patch, but it does not work without, either, because . itself is a valid suggestion too… So we are not degrading user experience in any way. We might support this use case with a more complex logic (always prune . ; prune .. unless [condition]).

If, barring all this, the feature is judged too disruptive a change, perhaps the new behavior could be controlled by a user option?

Implementation note: I’d have preferred to use the builtin filtering feature of compgen/complete (-X '@(.|..|*/.|*/..)') but it does not combine with filtering a custom xspec (we cannot use -X twice; there is a comment about that in _comp_delimited).

Regards,

Copy link
Collaborator

@akinomyoga akinomyoga left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implementation note: I’d have preferred to use the builtin filtering feature of compgen/complete (-X '@(.|..|*/.|*/..)') but it does not combine with filtering a custom xspec (we cannot use -X twice; there is a comment about that in _comp_delimited).

Technically one could do that by -X '!(!(pat1)|!(pat2))', but it is practically extremely slow due to Bash's implementation of extglob. (edit: Hmm, in this case, I think you want to remove candidates matching either pat1 or pat2, so you can simply do -X '@(pat1|pat2)'.) You can instead call compgen again for additional filtering by -X.

bash_completion Outdated Show resolved Hide resolved
bash_completion Outdated Show resolved Hide resolved
@akinomyoga
Copy link
Collaborator

There is a test failure in CI.

Also, can you add tests for the new behavior (in test/t/unit/test_unit_compgen_filedir.py)?

Copy link
Owner

@scop scop left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't had a real look here yet, but let's add the full rationale from the MR description to the commit message so one does not need to go search GitHub for it later.

@akinomyoga
Copy link
Collaborator

rebased

akinomyoga pushed a commit to Maelan/bash-completion that referenced this pull request Aug 11, 2024
Currently, "." and ".." are generated as completions when the current
path segment starts with a dot.  However, this impedes the completion
of any dotfiles when the current path segments is "." because the word
"." already matches the generated ".".  When the user attempts the
completion after inputting ".", the user is likely to intend to
complete a dotfile name as ".dotfile" (rather than to complete just a
slash as "./" because the user could just press "/" in such a case).
In this patch, we do not generate "." and ".." unless the user has
explicitly input "..".

The behavioral changes are summarized below.  Other possibilities of
the detailed behaviors are commented in the "[ Note: ... ]" sections.
If necessary, they can be reconsidered and adjusted in later commits.

* cmd .[TAB]

  When the current directory has no dotfiles (i.e., filenames starting
  with "."), it completed a slash.  Nothing will happen after this
  patch. [ Note: as another option, we might generate "." only when no
  dotfiles are found.  However, that might be annoying when the user
  tries to probe the existence of the dotfiles by pressing TAB, where
  the user does not expect the insertion of a slash. ]

  When the current directory has dotfiles, nothing happened.  After
  this patch, this will insert the common prefix of the dotfiles.
  Note that both "." and ".." are ignored in determining the common
  prefix.

* cmd ..[TAB]

  When the current directory has no files starting with "..", this
  completes a slash to form "../".  The behavior will not be changed
  by this patch. [ Note: as another option, we might disable ".." at
  all to be consistent with the case of ".".  However, the files
  starting with ".." are unlikely, and the user is less likely to
  probe the existence of the files starting with ".." by pressing TAB
  after "..".  For this reason, we generate ".." even if it would
  prevent completion of the common prefix of the files. ]

  When the current directory has files starting with "..", nothing
  happens with this.  The behavior will not be changed by this
  patch. [ Note: as another option, we might generate ".." only when
  there are no files starting with "..", but we here assume that the
  user may want to complete a slash as ".." even when there are files
  starting with "..". ]

References:
scop#364
scop#1230
akinomyoga pushed a commit to Maelan/bash-completion that referenced this pull request Aug 11, 2024
Currently, "." and ".." are generated as completions when the current
path segment starts with a dot.  However, this impedes the completion
of any dotfiles when the current path segments is "." because the word
"." already matches the generated ".".  When the user attempts the
completion after inputting ".", the user is likely to intend to
complete a dotfile name as ".dotfile" (rather than to complete just a
slash as "./" because the user could just press "/" in such a case).
In this patch, we do not generate "." and ".." unless the user has
explicitly input "..".

The behavioral changes are summarized below.  Other possibilities of
the detailed behaviors are commented in the "[ Note: ... ]" sections.
If necessary, they can be reconsidered and adjusted in later commits.

* cmd .[TAB]

  When the current directory has no dotfiles (i.e., filenames starting
  with "."), it completed a slash.  Nothing will happen after this
  patch. [ Note: as another option, we might generate "." only when no
  dotfiles are found.  However, that might be annoying when the user
  tries to probe the existence of the dotfiles by pressing TAB, where
  the user does not expect the insertion of a slash. ]

  When the current directory has dotfiles, nothing happened.  After
  this patch, this will insert the common prefix of the dotfiles.
  Note that both "." and ".." are ignored in determining the common
  prefix.

* cmd ..[TAB]

  When the current directory has no files starting with "..", this
  completes a slash to form "../".  The behavior will not be changed
  by this patch. [ Note: as another option, we might disable ".." at
  all to be consistent with the case of ".".  However, the files
  starting with ".." are unlikely, and the user is less likely to
  probe the existence of the files starting with ".." by pressing TAB
  after "..".  For this reason, we generate ".." even if it would
  prevent completion of the common prefix of the files. ]

  When the current directory has files starting with "..", nothing
  happens with this.  The behavior will not be changed by this
  patch. [ Note: as another option, we might generate ".." only when
  there are no files starting with "..", but we here assume that the
  user may want to complete a slash as ".." even when there are files
  starting with "..". ]

References:
scop#364
scop#1230
@akinomyoga
Copy link
Collaborator

I added necessary fixes. Each change is separated now, but they can be squashed before merging.

There is a test failure in CI.

7b4c531

Also, can you add tests for the new behavior (in test/t/unit/test_unit_compgen_filedir.py)?

I added them by myself f11c887.

I haven't had a real look here yet, but let's add the full rationale from the MR description to the commit message so one does not need to go search GitHub for it later.

I updated the commit message in 0973b43 (along with the first-line fix for Conventional Commits).

Currently, "." and ".." are generated as completions when the current
path segment starts with a dot.  However, this impedes the completion
of any dotfiles when the current path segments is "." because the word
"." already matches the generated ".".  When the user attempts the
completion after inputting ".", the user is likely to intend to
complete a dotfile name as ".dotfile" (rather than to complete just a
slash as "./" because the user could just press "/" in such a case).
In this patch, we do not generate "." and ".." unless the user has
explicitly input "..".

The behavioral changes are summarized below.  Other possibilities of
the detailed behaviors are commented in the "[ Note: ... ]" sections.
If necessary, they can be reconsidered and adjusted in later commits.

* cmd .[TAB]

  When the current directory has no dotfiles (i.e., filenames starting
  with "."), it completed a slash.  Nothing will happen after this
  patch. [ Note: as another option, we might generate "." only when no
  dotfiles are found.  However, that might be annoying when the user
  tries to probe the existence of the dotfiles by pressing TAB, where
  the user does not expect the insertion of a slash. ]

  When the current directory has dotfiles, nothing happened.  After
  this patch, this will insert the common prefix of the dotfiles.
  Note that both "." and ".." are ignored in determining the common
  prefix.

* cmd ..[TAB]

  When the current directory has no files starting with "..", this
  completes a slash to form "../".  The behavior will not be changed
  by this patch. [ Note: as another option, we might disable ".." at
  all to be consistent with the case of ".".  However, the files
  starting with ".." are unlikely, and the user is less likely to
  probe the existence of the files starting with ".." by pressing TAB
  after "..".  For this reason, we generate ".." even if it would
  prevent completion of the common prefix of the files. ]

  When the current directory has files starting with "..", nothing
  happens with this.  The behavior will not be changed by this
  patch. [ Note: as another option, we might generate ".." only when
  there are no files starting with "..", but we here assume that the
  user may want to complete a slash as ".." even when there are files
  starting with "..". ]

References:
scop#364
scop#1230

Co-authored-by: Koichi Murase <myoga.murase@gmail.com>
@akinomyoga
Copy link
Collaborator

squashed

@yedayak
Copy link
Collaborator

yedayak commented Nov 1, 2024

I pushed 88894da to add some testing for completing ..something files, I can squash if anyone thinks that's necessary. In general I'm in favor of this change.

These types of files are used by the go kubernetes atomic writer [0],
and presumably other types of systems, and we want to make sure they
will be completed correctly.

[0] https://pkg.go.dev/k8s.io/kubernetes/pkg/volume/util#AtomicWriter.Write
@scop scop merged commit 0e7a0cf into scop:main Nov 13, 2024
7 checks passed
@github-actions github-actions bot mentioned this pull request Nov 13, 2024
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.

4 participants