import { ShellCompDirective } from './t'; export function generate(name: string, exec: string): string { // Replace '-' and ':' with '_' for variable names const nameForVar = name.replace(/[-:]/g, '_'); // Shell completion directives const ShellCompDirectiveError = ShellCompDirective.ShellCompDirectiveError; const ShellCompDirectiveNoSpace = ShellCompDirective.ShellCompDirectiveNoSpace; const ShellCompDirectiveNoFileComp = ShellCompDirective.ShellCompDirectiveNoFileComp; const ShellCompDirectiveFilterFileExt = ShellCompDirective.ShellCompDirectiveFilterFileExt; const ShellCompDirectiveFilterDirs = ShellCompDirective.ShellCompDirectiveFilterDirs; const ShellCompDirectiveKeepOrder = ShellCompDirective.ShellCompDirectiveKeepOrder; return `# bash completion for ${name} # Define shell completion directives readonly ShellCompDirectiveError=${ShellCompDirectiveError} readonly ShellCompDirectiveNoSpace=${ShellCompDirectiveNoSpace} readonly ShellCompDirectiveNoFileComp=${ShellCompDirectiveNoFileComp} readonly ShellCompDirectiveFilterFileExt=${ShellCompDirectiveFilterFileExt} readonly ShellCompDirectiveFilterDirs=${ShellCompDirectiveFilterDirs} readonly ShellCompDirectiveKeepOrder=${ShellCompDirectiveKeepOrder} # Function to debug completion __${nameForVar}_debug() { if [[ -n \${BASH_COMP_DEBUG_FILE:-} ]]; then echo "$*" >> "\${BASH_COMP_DEBUG_FILE}" fi } # Function to handle completions __${nameForVar}_complete() { local cur prev words cword _get_comp_words_by_ref -n "=:" cur prev words cword local requestComp out directive # Build the command to get completions requestComp="${exec} complete -- \${words[@]:1}" # Add an empty parameter if the last parameter is complete if [[ -z "$cur" ]]; then requestComp="$requestComp ''" fi # Get completions from the program out=$(eval "$requestComp" 2>/dev/null) # Extract directive if present directive=0 if [[ "$out" == *:* ]]; then directive=\${out##*:} out=\${out%:*} fi # Process completions based on directive if [[ $((directive & $ShellCompDirectiveError)) -ne 0 ]]; then # Error, no completion return fi # Apply directives if [[ $((directive & $ShellCompDirectiveNoSpace)) -ne 0 ]]; then compopt -o nospace fi if [[ $((directive & $ShellCompDirectiveKeepOrder)) -ne 0 ]]; then compopt -o nosort fi if [[ $((directive & $ShellCompDirectiveNoFileComp)) -ne 0 ]]; then compopt +o default fi # Handle file extension filtering if [[ $((directive & $ShellCompDirectiveFilterFileExt)) -ne 0 ]]; then local filter="" for ext in $out; do filter="$filter|$ext" done filter="\\.($filter)" compopt -o filenames COMPREPLY=( $(compgen -f -X "!$filter" -- "$cur") ) return fi # Handle directory filtering if [[ $((directive & $ShellCompDirectiveFilterDirs)) -ne 0 ]]; then compopt -o dirnames COMPREPLY=( $(compgen -d -- "$cur") ) return fi # Process completions local IFS=$'\\n' local tab=$(printf '\\t') # Parse completions with descriptions local completions=() while read -r comp; do if [[ "$comp" == *$tab* ]]; then # Split completion and description local value=\${comp%%$tab*} local desc=\${comp#*$tab} completions+=("$value") else completions+=("$comp") fi done <<< "$out" # Return completions COMPREPLY=( $(compgen -W "\${completions[*]}" -- "$cur") ) } # Register completion function complete -F __${nameForVar}_complete ${name} `; }