blob: 0ba34401af04d82d1ad9e133999d287fdc5b365e (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
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
}
}
|