blob: 0ba34401af04d82d1ad9e133999d287fdc5b365e (
plain) (
tree)
|
|
package cmd
package completion
object Bash {
private def addCommands(command: Command): String = {
command.commands.map(c => s"""commands+=("$c")\n""").mkString
}
private def addFlags(command: Command): String = {
command.options.map { opt =>
val extra = if (opt.argumentRequired) "=" else ""
val short = opt.short.map(c => s"""flags+=("-${c}")""").getOrElse("")
s"""|flags+=("--${opt.long}$extra")
|$short
|""".stripMargin
}.mkString
}
private def commandBlocks(previous: String,
commands: Set[Command]): String = {
def block(previous: String, command: Command): String = {
s"""_${previous}_${command.name}() {
| ${addCommands(command)}
| ${addFlags(command)}
| true
|}
|""".stripMargin
}
if (commands.isEmpty) {
""
} else {
commands.map { cmd =>
block(previous, cmd) + commandBlocks(cmd.name, cmd.commands)
}.mkString
}
}
def completion(command: Command) = {
val name = command.name
s"""__${name}_contains_word() {
| local word="$$1"; shift
| for w in "$$@"; do
| [[ $$w = "$$word" ]] && return 0
| done
| return 1
|}
|
|__${name}_handle_reply() {
| case "$$cur" in
| -*)
| COMPREPLY=( $$(compgen -W "$${flags[*]}" -- "$$cur") )
| if [[ $${#COMPREPLY[@]} -eq 1 ]] && [[ $${COMPREPLY[0]} == *= ]]; then
| compopt -o nospace
| else
| compopt +o nospace
| fi
| ;;
| *)
| COMPREPLY=( $$(compgen -W "$${commands[*]}" -- "$$cur") )
| ;;
| esac
|}
|
|__${name}_handle_word() {
| if [[ $$c -ge $$cword ]]; then
| __${name}_handle_reply
| return
| fi
| if __${name}_contains_word "$${words[c]}" "$${commands[@]}"; then
| local next_command="$${last_command}_$${words[c]}"
| last_command="$$next_command"
| commands=()
| flags=()
| $$next_command
| fi
| c=$$((c+1))
| __${name}_handle_word
|}
|
|${commandBlocks(name, command.commands)}
|
|__${name}_start() {
| local words=("$${COMP_WORDS[@]}")
| local cword="$$COMP_CWORD"
| local cur="$${COMP_WORDS[COMP_CWORD]}"
| local c=0
| COMPREPLY=()
|
| local last_command="_${name}"
| local commands=()
| local flags=()
|
| ${addCommands(command)}
| ${addFlags(command)}
|
| __${name}_handle_word
|
| return 0
|}
|complete -o default -F __${name}_start ${name}
|""".stripMargin
}
}
|