Extend __fish_complete_suffix to support a virtual $PWD

In writing the completion script for openocd I found the need to
complete paths at the command-line as if they were relative to a
path other than the current $PWD. Given that `$PWD` is currently
global in fish (i.e. no side-effect free `cd` within a subshell)
this is probably good to have for other completions too.

This also fixes a bug in support for explicitly supplying the
description for completions via a `$argv` parameter, which prefixed
the description with `\t` (which is correct) except it did so in
the local scope within an `if` statement, meaning the changes never
had any effect and in the output the description was directly
concatenated to the completions, instead of separated by a tab.
This commit is contained in:
Mahmoud Al-Qudsi 2018-11-07 19:02:17 -06:00
parent 6b7501d715
commit da6937e0cf

View file

@ -2,7 +2,8 @@
# 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.
# 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"
@ -13,6 +14,7 @@ function __fish_complete_suffix -d "Complete using files"
set -l suff
set -l desc
set -l files
set -l prefix
switch (count $argv)
@ -31,11 +33,24 @@ function __fish_complete_suffix -d "Complete using files"
set suff $argv[2]
set desc $argv[3]
case 4
set comp $argv[1]
set suff $argv[2]
set desc $argv[3]
set prefix $argv[4]
# Only directories are supported as prefixes, and to use the same logic
# for both absolute prefixed paths and relative non-prefixed paths, $prefix
# must terminate in a `/` if it is present, so it can be unconditionally
# prefixed to any path to get the desired result.
if not string match -qr '/$' $prefix
set prefix $prefix/
end
end
# Strip leading ./ as it confuses the detection of base and suffix
# It is conditionally re-added below.
set base (string replace -r '^("\')?\\./' '' -- $comp | string trim -c '\'"') # " make emacs syntax highlighting happy
set base $prefix(string replace -r '^("\')?\\./' '' -- $comp | string trim -c '\'"') # " make emacs syntax highlighting happy
# echo "base: $base" > /dev/tty
# echo "suffix: $suff" > /dev/tty
@ -78,8 +93,13 @@ function __fish_complete_suffix -d "Complete using files"
end
if set -q files[1]
if not string match -q -- "$desc" ""
set -l desc "\t$desc"
if string match -qr -- . "$desc"
set desc "\t$desc"
end
if string match -qr -- . "$prefix"
# Ideally, only replace in the beginning of the string, but we have no
# way of doing a pcre2 escape so we can use a regex replace instead
set files (string replace $prefix "" $files)
end
printf "%s$desc\n" $files #| sort -u
end