TypePHP 编译器 https://swoole.com/aot/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

164 lines
5.2 KiB

<?php
namespace TypePhp\Cli;
final class BashCompletion
{
public static function render(): string
{
$options = self::words(CompletionMetadata::options());
$valueCases = '';
foreach (CompletionMetadata::values() as $option => $values) {
if (str_ends_with($option, '=')) {
continue;
}
$valueCases .= ' ' . self::bashPattern($option) . ")\n"
. ' COMPREPLY=( $(compgen -W '
. self::quote(self::words($values)) . ' -- "$current") )' . "\n"
. " return\n ;;\n";
}
$quotedOptions = self::quote($options);
$directoryOptions = implode('|', array_map(self::bashPattern(...), CompletionMetadata::directoryOptions()));
$pythonFileOptions = implode('|', array_map(self::bashPattern(...), CompletionMetadata::pythonFileOptions()));
$outputFileOptions = implode('|', array_map(self::bashPattern(...), CompletionMetadata::outputFileOptions()));
$equalsCases = '';
foreach (CompletionMetadata::values() as $option => $values) {
if (!str_ends_with($option, '=')) {
continue;
}
$prefix = substr($option, 0, -1);
$equalsCases .= ' ' . self::bashPattern($prefix) . "=*)\n"
. ' value="${current#' . $prefix . '=}"' . "\n"
. ' COMPREPLY=( $(compgen -W ' . self::quote(self::words($values))
. ' -P ' . self::quote($prefix . '=') . ' -- "$value") )' . "\n"
. " return\n ;;\n";
}
foreach (CompletionMetadata::directoryEqualsOptions() as $option) {
$prefix = substr($option, 0, -1);
$equalsCases .= ' ' . self::bashPattern($prefix) . "=*)\n"
. ' value="${current#' . $prefix . '=}"' . "\n"
. " compopt -o filenames\n"
. ' COMPREPLY=()' . "\n"
. ' while IFS= read -r candidate; do' . "\n"
. ' COMPREPLY+=("' . $prefix . '=${candidate}")' . "\n"
. ' done < <(compgen -d -- "$value")' . "\n"
. " return\n ;;\n";
}
$script = <<<BASH
# Bash completion for the TypePHP compiler.
# Generated by: tpc --generate-completion=bash
_typephp_tpc_complete_files()
{
local candidate
COMPREPLY=()
while IFS= read -r candidate; do
if [[ -d "\$candidate" || "\$candidate" == *.php || "\$candidate" == *.yml || "\$candidate" == *.yaml || "\$candidate" == *.prof ]]; then
COMPREPLY+=("\$candidate")
fi
done < <(compgen -f -- "\$1")
}
_typephp_tpc_complete_python_files()
{
local candidate
COMPREPLY=()
while IFS= read -r candidate; do
if [[ -d "\$candidate" || "\$candidate" == *.py ]]; then
COMPREPLY+=("\$candidate")
fi
done < <(compgen -f -- "\$1")
}
_typephp_tpc_complete_paths()
{
local mode="\$1" candidate
COMPREPLY=()
shift
while IFS= read -r candidate; do
COMPREPLY+=("\$candidate")
done < <(compgen "\$mode" -- "\$1")
}
_typephp_tpc()
{
local current previous value candidate
current="\${COMP_WORDS[COMP_CWORD]}"
previous=""
if (( COMP_CWORD > 0 )); then
previous="\${COMP_WORDS[COMP_CWORD - 1]}"
fi
local index
for ((index = 1; index < COMP_CWORD; index++)); do
if [[ "\${COMP_WORDS[index]}" == -- ]]; then
compopt -o default
return
fi
done
case "\$previous" in
{$valueCases} {$directoryOptions})
compopt -o filenames
_typephp_tpc_complete_paths -d "\$current"
return
;;
{$pythonFileOptions})
compopt -o filenames
_typephp_tpc_complete_python_files "\$current"
return
;;
{$outputFileOptions})
compopt -o filenames
_typephp_tpc_complete_paths -f "\$current"
return
;;
esac
case "\$current" in
-O[0-3])
COMPREPLY=("\$current")
return
;;
-O*)
value="\${current#-O}"
COMPREPLY=( $(compgen -W '0 1 2 3' -P '-O' -- "\$value") )
return
;;
{$equalsCases} -* )
COMPREPLY=( $(compgen -W {$quotedOptions} -- "\$current") )
return
;;
esac
compopt -o filenames
_typephp_tpc_complete_files "\$current"
}
complete -F _typephp_tpc tpc
complete -F _typephp_tpc ./tpc
complete -F _typephp_tpc tpc.php
complete -F _typephp_tpc bin/tpc.php
complete -F _typephp_tpc ./bin/tpc.php
BASH;
return $script . PHP_EOL;
}
/** @param list<string> $words */
private static function words(array $words): string
{
return implode(' ', $words);
}
private static function quote(string $value): string
{
return "'" . str_replace("'", "'\\''", $value) . "'";
}
private static function bashPattern(string $value): string
{
return str_replace(['\\', '*', '?', '[', ']'], ['\\\\', '\\*', '\\?', '\\[', '\\]'], $value);
}
}