scop / bash-completion

Programmable completion functions for bash
GNU General Public License v2.0
2.9k stars 380 forks source link

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

Open Maelan opened 3 months ago

Maelan commented 3 months ago

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,

akinomyoga commented 3 months ago

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)?

akinomyoga commented 1 month ago

rebased

akinomyoga commented 1 month ago

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

There is a test failure in CI.

7b4c5317d

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

I added them by myself f11c88762.

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 0973b43fd (along with the first-line fix for Conventional Commits).

akinomyoga commented 1 month ago

squashed