-
Notifications
You must be signed in to change notification settings - Fork 691
/
cabal
94 lines (84 loc) · 3.01 KB
/
cabal
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
# cabal command line completion
# Copyright 2007-2008 "Lennart Kolmodin" <kolmodin@gentoo.org>
# "Duncan Coutts" <dcoutts@gentoo.org>
#
# List cabal targets by type, pass:
# - test-suite for test suites
# - benchmark for benchmarks
# - executable for executables
# - executable|test-suite|benchmark for the three
_cabal_list()
{
for f in ./*.cabal; do
grep -Ei "^[[:space:]]*($1)[[:space:]]" "$f" |
sed -e "s/.* \([^ ]*\).*/\1/"
done
}
# List possible targets depending on the command supplied as parameter. The
# ideal option would be to implement this via --list-options on cabal directly.
# This is a temporary workaround.
_cabal_targets()
{
# If command ($*) contains build, repl, test or bench completes with
# targets of according type.
local comp
for comp in "$@"; do
[ "$comp" == new-build ] && _cabal_list "executable|test-suite|benchmark" && break
[ "$comp" == build ] && _cabal_list "executable|test-suite|benchmark" && break
[ "$comp" == repl ] && _cabal_list "executable|test-suite|benchmark" && break
[ "$comp" == run ] && _cabal_list "executable" && break
[ "$comp" == test ] && _cabal_list "test-suite" && break
[ "$comp" == bench ] && _cabal_list "benchmark" && break
done
}
# List possible subcommands of a cabal subcommand.
#
# In example "sandbox" is a cabal subcommand that itself has subcommands. Since
# "cabal --list-options" doesn't work in such cases we have to get the list
# using other means.
_cabal_subcommands()
{
local word
for word in "$@"; do
case "$word" in
sandbox)
# Get list of "cabal sandbox" subcommands from its help message.
"$1" help sandbox |
sed -n '1,/^Subcommands:$/d;/^Flags for sandbox:$/,$d;/^ /d;s/^\(.*\):/\1/p'
break # Terminate for loop.
;;
esac
done
}
__cabal_has_doubledash ()
{
local c=1
# Ignore the last word, because it is replaced anyways.
# This allows expansion for flags on "cabal foo --",
# but does not try to complete after "cabal foo -- ".
local n=$((${#COMP_WORDS[@]} - 1))
while [ $c -lt $n ]; do
if [ "--" = "${COMP_WORDS[c]}" ]; then
return 0
fi
((c++))
done
return 1
}
_cabal()
{
# no completion past cabal arguments.
__cabal_has_doubledash && return
# get the word currently being completed
local cur
cur=${COMP_WORDS[$COMP_CWORD]}
# create a command line to run
local cmd
# copy all words the user has entered
cmd=( ${COMP_WORDS[@]} )
# replace the current word with --list-options
cmd[${COMP_CWORD}]="--list-options"
# the resulting completions should be put into this array
COMPREPLY=( $( compgen -W "$( eval "${cmd[@]}" 2>/dev/null ) $( _cabal_targets "${cmd[@]}" ) $( _cabal_subcommands "${COMP_WORDS[@]}" )" -- "$cur" ) )
}
complete -F _cabal -o default cabal