From da6937e0cf7055119b76df4b68a560c982cac30e Mon Sep 17 00:00:00 2001 From: Mahmoud Al-Qudsi Date: Wed, 7 Nov 2018 19:02:17 -0600 Subject: [PATCH] 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. --- share/functions/__fish_complete_suffix.fish | 28 ++++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/share/functions/__fish_complete_suffix.fish b/share/functions/__fish_complete_suffix.fish index 6be18ea6e..d7861e953 100644 --- a/share/functions/__fish_complete_suffix.fish +++ b/share/functions/__fish_complete_suffix.fish @@ -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