mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-11-25 09:17:12 +08:00
Add a completion helper function to generate permutation completions
I've been needing this for some time to generate completions for functions that we can dynamically generate completions for that take one or more comma-separated values in any order.
This commit is contained in:
parent
6dbae76b24
commit
f342ae6a1c
44
share/functions/__fish_concat_completions.fish
Normal file
44
share/functions/__fish_concat_completions.fish
Normal file
|
@ -0,0 +1,44 @@
|
|||
# This function is intended to be used to generate completions in `-a "(...)"` calls for arguments that take 1..n values
|
||||
# separated by commas and we dynamically or statically generated a list of n values that must be combined and permuted
|
||||
# in order to appease both the `complete` machinery and the target application.
|
||||
#
|
||||
# TODO: Make this work with completions that have their description appended after a \t
|
||||
|
||||
function __fish_concat_completions -d "Generate completions that are specified as comma-separated values from stdin source"
|
||||
type -q awk || return;
|
||||
|
||||
set -l token (commandline -ct)
|
||||
# We want to filter out suggestions the user has already entered.
|
||||
set -l extant (string split -- ',' $token)
|
||||
set -l filter (printf '^%s$\n' (printf '%s\n' $extant | string escape --style=regex) | string join '|')
|
||||
# Work around the insanity of trying to read from stdin within a function. Note that we can't place the
|
||||
# `read` call in between () to capture the output because that breaks its connection to stdin.
|
||||
while read -l line;
|
||||
echo $line;
|
||||
end | string match -er '.' | string match -rv -- $filter | string replace -r '^' -- (string replace -rf '^(.+),.*$' '$1,' $token; or echo "")
|
||||
|
||||
return
|
||||
# Verified compatible with bsd awk and gnu awk
|
||||
awk '
|
||||
{
|
||||
lines[NR-1] = $0
|
||||
}
|
||||
END {
|
||||
n = NR
|
||||
for (k = 1; k <= n; k++) {
|
||||
generate_permutations(lines, n, k)
|
||||
}
|
||||
}
|
||||
function generate_permutations(arr, total_len, perm_len, prefix, _i, _swap) {
|
||||
if (perm_len == 0) {
|
||||
print prefix
|
||||
return
|
||||
}
|
||||
for (_i = 0; _i < total_len; _i++) {
|
||||
_swap = arr[total_len-1]; arr[total_len-1] = arr[_i]; arr[_i] = _swap
|
||||
generate_permutations(arr, total_len-1, perm_len-1, prefix arr[total_len-1] (perm_len == 1 ? "" : ","))
|
||||
arr[_i] = arr[total_len-1]; arr[total_len-1] = _swap
|
||||
}
|
||||
}
|
||||
'
|
||||
end
|
Loading…
Reference in New Issue
Block a user