Skip to content

Commit

Permalink
feat(_comp_compgen_filedir{,_xspec}): do not generate "." and ".."
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Maelan authored and akinomyoga committed Aug 11, 2024
1 parent b44b29c commit 0973b43
Showing 1 changed file with 22 additions and 0 deletions.
22 changes: 22 additions & 0 deletions bash_completion
Original file line number Diff line number Diff line change
Expand Up @@ -1148,6 +1148,17 @@ _comp_compgen_filedir()
compopt -o filenames 2>/dev/null
fi

# Remove . and .. (as well as */. and */..) from suggestions,
# unless .. or */.. was typed explicitly by the user
# (for users who use tab-completion to append a slash after '..')
if [[ "${cur}" != @(..|*/..) ]]; then
local i
for i in "${!toks[@]}" ; do
[[ "${toks[$i]}" == @(.|..|*/.|*/..) ]] && \
unset -v "toks[$i]"
done
fi

# Note: bash < 4.4 has a bug that all the elements are connected with
# ${v+"${a[@]}"} when IFS does not contain whitespace.
local IFS=$' \t\n'
Expand Down Expand Up @@ -3042,6 +3053,17 @@ _comp_compgen_filedir_xspec()
((${#toks[@]})) || return 1
# Remove . and .. (as well as */. and */..) from suggestions,
# unless .. or */.. was typed explicitly by the user
# (for users who use tab-completion to append a slash after '..')
if [[ "${cur}" != @(..|*/..) ]]; then
local i
for i in "${!toks[@]}" ; do
[[ "${toks[$i]}" == @(.|..|*/.|*/..) ]] && \
unset -v "toks[$i]"
done
fi
compopt -o filenames
_comp_compgen -RU toks -- -W '"${toks[@]}"'
}
Expand Down

0 comments on commit 0973b43

Please sign in to comment.