Separate completion metadata from literal choices
This commit is contained in:
@@ -28,12 +28,15 @@ func CompletionReply(result commandmeta.CompletionResult) (string, error) {
|
||||
default:
|
||||
return "", fmt.Errorf("unsupported completion suggestion strategy")
|
||||
}
|
||||
var output strings.Builder
|
||||
if result.Kind != commandmeta.CompletionNone && result.Prefix != "" {
|
||||
output.WriteString(completionPathPrefixMarker)
|
||||
output.WriteString(result.Prefix)
|
||||
output.WriteByte('\n')
|
||||
// The first line is always metadata, even for a whole-word replacement.
|
||||
// Remaining lines before the directive are exclusively literal candidates.
|
||||
if strings.ContainsAny(result.Prefix, "\x00\r\n\t") {
|
||||
return "", fmt.Errorf("unrepresentable completion prefix")
|
||||
}
|
||||
var output strings.Builder
|
||||
output.WriteString(completionPathPrefixMarker)
|
||||
output.WriteString(result.Prefix)
|
||||
output.WriteByte('\n')
|
||||
if result.Kind == commandmeta.CompletionChoices {
|
||||
for _, choice := range result.Choices {
|
||||
if choice.Value == "" || strings.ContainsAny(choice.Value, "\x00\r\n\t") {
|
||||
@@ -145,20 +148,29 @@ func adjustBashCompletion(script, name string) (string, error) {
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
parsePrefix := `if [[ ${out} == ` + completionPathPrefixMarker + `-* ]]; then
|
||||
completionPrefix=${out%%$'\n'*}
|
||||
completionPrefix=${completionPrefix#` + completionPathPrefixMarker + `}
|
||||
completionOriginalCur=$cur
|
||||
if [[ $completionOriginalCur == "$completionPrefix"* ]]; then
|
||||
if [[ $out == *$'\n'* ]]; then out=${out#*$'\n'}; else out=; fi
|
||||
cur=${completionOriginalCur#"$completionPrefix"}
|
||||
else
|
||||
completionPrefix=""
|
||||
fi
|
||||
parsePrefix := `if [[ ${out} != ` + completionPathPrefixMarker + `* ]]; then
|
||||
compopt +o default
|
||||
return
|
||||
fi
|
||||
completionPrefix=${out%%$'\n'*}
|
||||
completionPrefix=${completionPrefix#` + completionPathPrefixMarker + `}
|
||||
completionOriginalCur=$cur
|
||||
if [[ $completionOriginalCur != "$completionPrefix"* ]]; then
|
||||
compopt +o default
|
||||
return
|
||||
fi
|
||||
if [[ $out == *$'\n'* ]]; then out=${out#*$'\n'}; else out=; fi
|
||||
cur=${completionOriginalCur#"$completionPrefix"}
|
||||
|
||||
# Separate activeHelp from normal completions`
|
||||
script, err = replaceCompletionText(script, `# Separate activeHelp from normal completions`, parsePrefix)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
script, err = replaceCompletionSection(script, " local activeHelpMarker=", "\n}\n", ` while IFS='' read -r comp; do
|
||||
[[ -z $comp ]] || completions+=("$comp")
|
||||
done <<<"${out}"
|
||||
`)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -196,19 +208,23 @@ func adjustZshCompletion(script string) (string, error) {
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
script, err = replaceCompletionText(script, `local activeHelpMarker="_activeHelp_ "`, `if [[ "$out" == `+completionPathPrefixMarker+`-* ]]; then
|
||||
local pathPrefix="${out%%$'\n'*}"
|
||||
pathPrefix="${pathPrefix#`+completionPathPrefixMarker+`}"
|
||||
if [[ "$lastParam" == "$pathPrefix"* ]]; then
|
||||
if [[ $out == *$'\n'* ]]; then out="${out#*$'\n'}"; else out=; fi
|
||||
flagPrefix="$pathPrefix"
|
||||
fi
|
||||
fi
|
||||
script, err = replaceCompletionSection(script, ` local activeHelpMarker=`, " if [ $((directive & shellCompDirectiveNoSpace))", ` [[ "$out" == `+completionPathPrefixMarker+`* ]] || return 1
|
||||
flagPrefix="${out%%$'\n'*}"
|
||||
flagPrefix="${flagPrefix#`+completionPathPrefixMarker+`}"
|
||||
[[ "$lastParam" == "$flagPrefix"* ]] || return 1
|
||||
if [[ $out == *$'\n'* ]]; then out="${out#*$'\n'}"; else out=; fi
|
||||
if [[ -n "$flagPrefix" ]]; then
|
||||
prefixArgs=(-P "$flagPrefix")
|
||||
fi
|
||||
local tab="$(printf '\t')"
|
||||
while IFS= read -r comp; do
|
||||
if [[ -n "$comp" ]]; then
|
||||
comp=${comp//:/\\:}
|
||||
completions+=("${comp//$tab/:}")
|
||||
fi
|
||||
done <<<"$out"
|
||||
|
||||
local activeHelpMarker="_activeHelp_ "`)
|
||||
`)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -272,15 +288,14 @@ func adjustFishCompletion(script, name string) (string, error) {
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
script, err = replaceCompletionSection(script, " # For Fish, when completing a flag", ` printf "%s\n" "$directiveLine"`, ` set -l flagPrefix ""
|
||||
if set -q comps[1]; and string match -q -- '`+completionPathPrefixMarker+`-*' "$comps[1]"
|
||||
set -l candidatePrefix (string replace -- '`+completionPathPrefixMarker+`' '' "$comps[1]")
|
||||
if test (string sub -l (string length -- "$candidatePrefix") -- "$lastArg") = "$candidatePrefix"
|
||||
set flagPrefix "$candidatePrefix"
|
||||
set -e comps[1]
|
||||
end
|
||||
script, err = replaceCompletionSection(script, " # For Fish, when completing a flag", ` printf "%s\n" "$directiveLine"`, ` if not set -q comps[1]; or not string match -q -- '`+completionPathPrefixMarker+`*' "$comps[1]"
|
||||
printf ":%s\n" `+fmt.Sprint(spfcobra.ShellCompDirectiveError)+`
|
||||
return
|
||||
end
|
||||
printf "%s%s\n" '`+completionPathPrefixMarker+`' "$flagPrefix"
|
||||
set -l flagPrefix (string replace -- '`+completionPathPrefixMarker+`' '' "$comps[1]")
|
||||
set -q flagPrefix[1]; or set flagPrefix ""
|
||||
printf "%s\n" "$comps[1]"
|
||||
set -e comps[1]
|
||||
for comp in $comps
|
||||
printf "%s%s\n" "$flagPrefix" "$comp"
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user