__fish_complete_suffix: complete all files, but sort files with matching suffix first

See #7040 and others.
This commit is contained in:
Johannes Altmanninger 2020-12-13 08:27:21 +01:00
parent d18e1c7bca
commit bae75c96d9
3 changed files with 17 additions and 11 deletions

View File

@ -251,6 +251,7 @@ Completions
- Lots of improvements to completions.
- Improvements to the manpage completion generator (:issue:`7086`).
- Significant performance improvements to completion of the available commands (:issue:`7153`).
- ``__fish_complete_suffix`` completes any file but sorts files with matching suffix first (:issue:`7040`). Previously, it only completed files with matching suffix.
Deprecations and removed features
---------------------------------

View File

@ -83,7 +83,7 @@ Functions beginning with the string ``__fish_print_`` print a newline separated
- ``__fish_complete_pids`` prints a list of all processes IDs with the command name as description.
- ``__fish_complete_suffix SUFFIX`` performs file completion allowing only files ending in SUFFIX, with an optional description.
- ``__fish_complete_suffix SUFFIX`` performs file completion but sorts files ending in SUFFIX first. This is useful in conjunction with ``complete --keep-order``.
- ``__fish_complete_users`` prints a list of all users with their full name as description.

View File

@ -1,10 +1,11 @@
#
# Find files that complete $argv[1], has the suffix $argv[2], and
# output them as completions with the optional description $argv[3] Both
# $argv[1] and $argv[3] are optional, if only one is specified, it is
# assumed to be the argument to complete. If $argv[4] is present, it is
# treated as a prefix for the path, i.e. in lieu of $PWD.
#
# Find files that complete $argv[1], has the suffix $argv[2], and output them
# as completions with the optional description $argv[3]. Then, also output
# completions for the files that don't have the suffix, so you want to use
# "complete -k" on the output. Both $argv[1] and $argv[3] are optional,
# if only one is specified, it is assumed to be the argument to complete. If
# $argv[4] is present, it is treated as a prefix for the path, i.e. in lieu
# of $PWD.
function __fish_complete_suffix -d "Complete using files"
@ -48,17 +49,21 @@ function __fish_complete_suffix -d "Complete using files"
end
end
# Simple and common case: no prefix, just complete normally and filter out unwanted suffixes.
# Simple and common case: no prefix, just complete normally and sort matching files first.
if test -z $prefix
set -l suffix (string escape --style=regex -- $suff)
# Use normal file completions.
set files (complete -C "__fish_command_without_completions $comp" | string match -r "^.*(?:$suffix|/)\$")
set files (complete -C "__fish_command_without_completions $comp")
set -l files_with_suffix (string match -r -- "^.*$suffix\$" $files)
set -l directories (string match -r -- '^.*/$' $files)
set files $files_with_suffix $directories $files
else
# Strip leading ./ as it confuses the detection of base and suffix
# It is conditionally re-added below.
set base $prefix(string replace -r '^("\')?\\./' '' -- $comp | string trim -c '\'"') # " make emacs syntax highlighting happy
set -l all
set -l files_with_suffix
set -l dirs
# If $comp is "./ma" and the file is "main.py", we'll catch that case here,
# but complete.cpp will not consider it a match, so we have to output the
@ -67,7 +72,7 @@ function __fish_complete_suffix -d "Complete using files"
# Also do directory completion, since there might be files with the correct
# suffix in a subdirectory.
set all $base*
set all (string match -r -- ".*"(string escape --style=regex -- $suff) $all)
set files_with_suffix (string match -r -- ".*"(string escape --style=regex -- $suff) $all)
if not string match -qr '/$' -- $suff
set dirs $base*/
@ -82,7 +87,7 @@ function __fish_complete_suffix -d "Complete using files"
end
end
set files $all $dirs
set files $files_with_suffix $dirs $all
if string match -qr '^\\./' -- $comp
set files ./$files
else