forked from mernen/completion-ruby
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcompletion-rake
More file actions
173 lines (157 loc) · 5.2 KB
/
completion-rake
File metadata and controls
173 lines (157 loc) · 5.2 KB
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#! bash
# bash completion for the `rake` command.
#
# Copyright (c) 2008-2010 Daniel Luz <dev at mernen dot com>.
# Distributed under the MIT license.
# http://mernen.com/projects/completion-ruby
#
# To use, source this file on bash:
# . completion-rake
__rake() {
local rake_cmd="$1"
# For the current word, $2 returns just the part after the last colon.
# ${COMP_WORDS[$COMP_CWORD]} used to work fine, but for some reason
# bash 4.1.5 on Ubuntu 10.10 will treat the colons as separate words.
local cur="$(<<<"${COMP_LINE:0:$COMP_POINT}" sed 's/^.* //')"
local prev=$3
COMPREPLY=()
case $prev in
-f | --rakefile | -r | --require)
# leave COMPREPLY blank, let the default handle it
return;;
-I | --libdir | -R | --rakelibdir)
if type -t _filedir >/dev/null; then
_filedir -d
# suffix all entries with a slash
COMPREPLY=("${COMPREPLY[@]/%//}")
fi
return;;
*)
if [[ $cur = -* ]]; then
local options="
-C --classic-namespace -D --describe -n --dry-run -h --help
-I --libdir -N --nosearch -P --prereqs -q --quiet -f --rakefile
-R --rakelibdir -r --require -s --silent -T --tasks -t --trace
-v --verbose -V --version"
COMPREPLY=($(compgen -W "$options" -- "$cur"))
elif [[ $cur = *'['* ]]; then
# parameter completion (using default compgen)
# $cur: example[param1,param2
# $args: param1,param2
local args=${cur#*[}
# $last_arg: param2
local last_arg=${args##*,}
# $prefix: example[param1,
local prefix=${cur%"$last_arg"}
# ugh, ugly hack here, but I'm out of ideas
local old_ifs=$IFS IFS=$'\n'
COMPREPLY=($(compgen -o default -- "$last_arg"))
local IFS=$old_ifs
# escape space characters...
COMPREPLY=("${COMPREPLY[@]// /\ }")
# and prepend the prefix to all completion options
COMPREPLY=("${COMPREPLY[@]/#/$prefix}")
__rake_remove_namespaces
# don't perform usual post-processing
return
else
local rakefile rakedir
__rake_get_rakefile || return
COMPREPLY=($(compgen -W "$(__rake_tasks)" -- "$cur"))
fi
esac
__rake_remove_namespaces
# append a space to all options...
COMPREPLY=("${COMPREPLY[@]/%/ }")
# ...and remove [parameters] from tasks
COMPREPLY=("${COMPREPLY[@]/[*/}")
}
# bash treats ":" as a path separator, borking our completion on
# namespaced tasks. This function removes whatever the user already typed
# until the last colon.
__rake_remove_namespaces() {
if [[ $cur = *:* ]]; then
local prefix=${cur%:*}:
COMPREPLY=("${COMPREPLY[@]#"$prefix"}")
fi
}
# Finds the appropriate rakefile, given the arguments in the command-line and
# the current directory.
#
# Writes to `$rakefile` the path of the file, and sets `$rakedir` if the
# command must be run from a different directory.
#
# Since this function sets new variables, it must NOT run on a subshell.
#
# Note that `$rakefile` is also NOT guaranteed to be absolute!
__rake_get_rakefile() {
# look for --rakefile or -f
# $rakedir is not defined in this case, regardless of where $rakefile lives
local i
for ((i=0; i <= $COMP_CWORD - 1; ++i)); do
local arg=${COMP_WORDS[$i]}
case $arg in
--rakefile | -f)
rakefile=${COMP_WORDS[$(($i + 1))]}
return;;
--rakefile=* | -f=*)
rakefile=${arg#*=}
return;;
esac
done
# look for rakefiles in the directory hierarchy
# note that the command should run on the context of the directory where
# the rakefile is found, so $rakedir has to be set
local fn
pushd . &>/dev/null
while true; do
for fn in rakefile Rakefile; do
if [[ -f $fn ]]; then
rakedir=$(pwd)
rakefile=$rakedir/$fn
popd &>/dev/null
return
fi
done
cd ..
[[ $(pwd) = / ]] && break
done
popd >/dev/null
return 1
}
# Outputs the list of possible tasks for the given rakefile and rakedir,
# one task per line.
#
# Parameters can be passed either as environment variables `$rakefile` and
# `$rakedir` or via positional arguments:
# (__rake_tasks <rakefile> [rakedir])
__rake_tasks() {
local rakefile=${1:-$rakefile}
local rakedir=${2:-$rakedir}
[[ -f $rakefile ]] || return 1
rakefile=$(ruby -e 'puts File.expand_path(ARGV[0])' -- "$rakefile")
local cachedir=$HOME/.local/share/completion-cache
local cachefile=$cachedir/rake
# uncomment the following lines if you prefer individual caches:
## local cachedir=$HOME/.local/share/completion-cache/rake
## local cachefile=$cachedir/${rakefile//\//%}
local tasks
if [[ $cachefile -nt $rakefile &&
$(head -n 1 -- "$cachefile") = $rakefile ]]; then
tail -n +2 -- "$cachefile"
else
[[ -d $rakedir ]] && cd "$rakedir"
local rake_cmd=${rake_cmd:-rake}
tasks=$("$rake_cmd" --rakefile "$rakefile" --silent -P 2>/dev/null | grep '^rake ' | sort -u | cut -b6-)
if [[ $tasks ]]; then
# attempt to ensure $cachedir exists and is a directory
# before writing to $cachefile
([[ -f $cachedir ]] && rm -- "$cachedir";
mkdir -p -- "$cachedir" &&
echo "$rakefile"$'\n'"$tasks" >"$cachefile") 2>/dev/null
echo "$tasks"
fi
fi
}
complete -F __rake -o default -o nospace rake rake1.8 rake1.9
# vim: ai ft=sh sw=2 sts=2 et