Improved bash completion script.
Warning: I tried a bunch of things and it looks like it works, but I'm not using bash regularly so there might be some problems in this. Committing by request of the bashers. It would still need some work to make it work as (I think) was intended. For example _find_exe() should be used to find the current executable when completing, but it's used at the toplevel.
This commit is contained in:
parent
6260b4c239
commit
8fc49d41cf
|
@ -1,210 +1,181 @@
|
||||||
# -*- mode: shell-script; sh-basic-offset: 2; indent-tabs-mode: nil -*-
|
# -*- mode: shell-script; sh-basic-offset: 2; indent-tabs-mode: nil -*-
|
||||||
# ex: ts=2 sw=2 noet filetype=sh
|
# ex: ts=2 sw=2 noet filetype=sh
|
||||||
|
|
||||||
# to enable this, add the following line to ~/.bash_completion you
|
# To enable this, add the following line to ~/.bash_completion
|
||||||
# will need to make sure that you've enable bash completion more
|
|
||||||
# generally, usually via '. /etc/bash_completion'
|
|
||||||
#
|
#
|
||||||
# source $PLTHOME/collects/meta/contrib/completion/racket-completion.bash
|
# source $PLTHOME/collects/meta/contrib/completion/racket-completion.bash
|
||||||
#
|
#
|
||||||
# Change $PLTHOME to whatever references your Racket installation
|
# Change $PLTHOME to whatever references your Racket installation. You
|
||||||
|
# will need to make sure that you have bash completions enabled, usually
|
||||||
|
# with "source /etc/bash_completion".
|
||||||
|
|
||||||
# this completes only *.{rkt,ss,scm,scrbl} files unless there are
|
# This completes only *.{rkt,ss,scm,scrbl} files unless there are none,
|
||||||
# none, in which case it completes other things
|
# in which case it completes other things.
|
||||||
_smart_filedir()
|
_racket_filedir() {
|
||||||
{
|
|
||||||
COMPREPLY=()
|
COMPREPLY=()
|
||||||
_filedir '@(rkt|rktl|ss|scm|scrbl)'
|
_filedir "@(rkt|rktl|ss|scm|scrbl)"
|
||||||
if [[ ${#COMPREPLY[@]} -eq 0 ]]; then
|
if [[ "${#COMPREPLY[@]}" -eq 0 ]]; then _filedir; fi
|
||||||
_filedir
|
|
||||||
fi
|
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_find_exe()
|
_find_exe() {
|
||||||
{
|
local exename="$1"
|
||||||
local exename=$1
|
local dir="$(dirname "${COMP_WORDS[0]}")"
|
||||||
local path=`dirname "${COMP_WORDS[0]}"`
|
local exe="$(basename "${COMP_WORDS[0]}")"
|
||||||
local old_exe=`basename "${COMP_WORDS[0]}"`
|
if [[ "$dir" != "." || "${COMP_WORDS[0]}" = "$dir/$exe" ]]; then
|
||||||
if [ "${path}" = "." ]
|
echo "$dir/$exename"
|
||||||
then
|
|
||||||
if [ "${COMP_WORDS[0]}" = "${path}/${old_exe}" ]
|
|
||||||
then
|
|
||||||
echo "${path}/${exename}"
|
|
||||||
else
|
|
||||||
echo ${exename}
|
|
||||||
fi
|
|
||||||
else
|
else
|
||||||
echo "${path}/${exename}"
|
echo "$exename"
|
||||||
fi
|
fi
|
||||||
return 0
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_racket()
|
_racket() {
|
||||||
{
|
|
||||||
local cur prev singleopts doubleopts
|
local cur prev singleopts doubleopts
|
||||||
COMPREPLY=()
|
COMPREPLY=()
|
||||||
cur=`_get_cword`
|
cur="$(_get_cword)"
|
||||||
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
||||||
doubleopts="--help --version --eval --load --require --lib --script --require-script\
|
doubleopts="--help --version --eval --load --require --lib --script"
|
||||||
--main --repl --no-lib --version --warn --syslog --collects --search --addon --no-compiled --no-init-file"
|
doubleopts+=" --require-script --main --repl --no-lib --version --warn"
|
||||||
singleopts="-h -e -f -t -l -p -r -u -k -m -i -n -v -W -L -X -S -A -I -U -N -j -d -b -c -q"
|
doubleopts+=" --syslog --collects --search --addon --no-compiled"
|
||||||
|
doubleopts+=" --no-init-file"
|
||||||
|
singleopts="-h -e -f -t -l -p -r -u -k -m -i -n -v -W -L -X -S -A -I -U"
|
||||||
|
singleopts+=" -N -j -d -b -c -q"
|
||||||
warnlevels="none fatal error warning info debug"
|
warnlevels="none fatal error warning info debug"
|
||||||
|
|
||||||
# if '--' is already given, complete all kind of files, but no options
|
# if "--" is already given, complete all kind of files, but no options
|
||||||
for (( i=0; i < ${#COMP_WORDS[@]}-1; i++ )); do
|
for (( i=0; i < ${#COMP_WORDS[@]}-1; i++ )); do
|
||||||
if [[ ${COMP_WORDS[i]} == -- ]]; then
|
if [[ "${COMP_WORDS[i]}" == "--" ]]; then _racket_filedir; return; fi
|
||||||
_smart_filedir
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
done
|
done
|
||||||
|
|
||||||
# -k takes *two* integer arguments
|
# -k takes *two* integer arguments
|
||||||
if [[ 2 < ${#COMP_WORDS[@]} ]]; then
|
if [[ 2 < "${#COMP_WORDS[@]}" ]]; then
|
||||||
if [[ ${COMP_WORDS[COMP_CWORD-2]} == -k ]]; then
|
if [[ "${COMP_WORDS[COMP_CWORD-2]}" == "-k" ]]; then return; fi
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
case "$cur" in
|
||||||
case "${cur}" in
|
"--"* )
|
||||||
--*)
|
COMPREPLY=( $(compgen -W "$doubleopts" -- "$cur") )
|
||||||
COMPREPLY=( $(compgen -W "${doubleopts}" -- ${cur}) )
|
|
||||||
;;
|
;;
|
||||||
-*)
|
"-"* )
|
||||||
COMPREPLY=( $(compgen -W "${singleopts}" -- ${cur}) )
|
COMPREPLY=( $(compgen -W "$singleopts" -- "$cur") )
|
||||||
;;
|
;;
|
||||||
*)
|
* )
|
||||||
case "${prev}" in
|
case "$prev" in
|
||||||
# these do not take anything completable as arguments
|
# these do not take anything completable as arguments
|
||||||
--help|-h|-e|--eval|-p|-k)
|
"--help" | "-h" | "-e" | "--eval" | "-p" | "-k" )
|
||||||
;;
|
;;
|
||||||
# these take dirs (not files) as arguments
|
# these take dirs (not files) as arguments
|
||||||
-X|-S|-A|--collects|--search|--addon)
|
"-X" | "-S" | "-A" | "--collects" | "--search" | "--addon" )
|
||||||
_filedir '-d'
|
_filedir -d
|
||||||
;;
|
;;
|
||||||
# these take warnlevels as arguments
|
# these take warnlevels as arguments
|
||||||
-W|--warn|-L|--syslog)
|
"-W" | "--warn" | "-L" | "--syslog" )
|
||||||
COMPREPLY=( $(compgen -W "${warnlevels}" -- ${cur}) )
|
COMPREPLY=( $(compgen -W "$warnlevels" -- "$cur") )
|
||||||
;;
|
;;
|
||||||
# otherwise, just a file
|
# otherwise, just a file
|
||||||
*)
|
* )
|
||||||
_smart_filedir
|
_racket_filedir
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
complete -F _racket $filenames racket
|
|
||||||
complete -F _racket $filenames gracket
|
|
||||||
complete -F _racket $filenames gracket-text
|
|
||||||
|
|
||||||
_raco_cmd=$(_find_exe "raco" )
|
complete -F _racket racket
|
||||||
|
complete -F _racket gracket
|
||||||
|
complete -F _racket gracket-text
|
||||||
|
|
||||||
|
_raco_cmd="$(_find_exe "raco")"
|
||||||
|
|
||||||
_raco_planet()
|
_raco_planet() {
|
||||||
{
|
local cur="${COMP_WORDS[COMP_CWORD]}"
|
||||||
local cur="${COMP_WORDS[COMP_CWORD]}"
|
local planetcmds=$(
|
||||||
local planetcmds=$( echo '' '--help' ; for x in `${_raco_cmd} planet --help 2>&1 | sed -n -e 's/^ raco planet \(.[^ ]*\).*/\1/p'` ; do echo ${x} ; done )
|
printf '%s\n' "--help"
|
||||||
COMPREPLY=( $(compgen -W "${planetcmds}" -- ${cur}) )
|
"${_raco_cmd}" planet --help 2>&1 | awk '/^ *raco planet / { print $3 }'
|
||||||
|
)
|
||||||
|
COMPREPLY=( $(compgen -W "$planetcmds" -- "$cur") )
|
||||||
}
|
}
|
||||||
|
|
||||||
_raco_cmds=$()
|
_raco_cmds=$()
|
||||||
_racket_cmd=$(_find_exe "racket" )
|
_racket_cmd="$(_find_exe "racket")"
|
||||||
|
|
||||||
_raco_help()
|
_raco_help() {
|
||||||
{
|
local cur="${COMP_WORDS[COMP_CWORD]}"
|
||||||
local cur="${COMP_WORDS[COMP_CWORD]}"
|
if [[ ${#_raco_cmds[@]} -eq 0 ]]; then
|
||||||
if [ ${#_raco_cmds[@]} -eq 0 ]; then
|
_raco_cmds=$(
|
||||||
# removing the empty string on the next line breaks things. such as my brain.
|
echo "help"
|
||||||
_raco_cmds=$( echo '' 'help' ; for x in `${_racket_cmd} -e '(begin (require raco/all-tools) (for ([(k v) (all-tools)]) (printf "~a\n" k)))'` ; do echo ${x} ; done )
|
"$_racket_cmd" -e '(begin (require raco/all-tools)
|
||||||
fi
|
(for ([(k v) (all-tools)]) (printf "~a\n" k)))'
|
||||||
COMPREPLY=( $(compgen -W "${_raco_cmds}" -- ${cur}) )
|
)
|
||||||
|
fi
|
||||||
|
COMPREPLY=( $(compgen -W "$_raco_cmds" -- "$cur") )
|
||||||
}
|
}
|
||||||
|
|
||||||
_racket_collects_dirs=()
|
_racket_collects_dirs=()
|
||||||
|
|
||||||
_complete_collects()
|
_complete_collects() {
|
||||||
{
|
local cur="$1"
|
||||||
local cur=$1
|
if [[ "${#_racket_collects_dirs[@]}" -eq 0 ]]; then
|
||||||
if [ ${#_racket_collects_dirs[@]} -eq 0 ]; then
|
_racket_collects_dirs=(
|
||||||
_racket_collects_dirs=( $( for x in `${_racket_cmd} -e '(for-each displayln (map path->string (current-library-collection-paths)))'`; do echo "${x}/" ; done ) )
|
$( $_racket_cmd -e
|
||||||
|
'(for-each displayln (current-library-collection-paths))' )
|
||||||
|
)
|
||||||
fi
|
fi
|
||||||
local wordlist=""
|
local wordlist=""
|
||||||
for dir in ${_racket_collects_dirs[@]}; do
|
for dir in "${_racket_collects_dirs[@]}"; do
|
||||||
wordlist="$wordlist "$( for x in $(compgen -d "${dir}"); do basename "${x}"; done )
|
wordlist="$wordlist $(for x in $(compgen -d "$dir"); do basename "$x"; done)"
|
||||||
done
|
done
|
||||||
COMPREPLY=( $(compgen -W "${wordlist}" -- ${cur}) )
|
COMPREPLY=( $(compgen -W "$wordlist" -- "$cur") )
|
||||||
}
|
}
|
||||||
|
|
||||||
_raco_setup()
|
_raco_setup()
|
||||||
{
|
{
|
||||||
local cur="${COMP_WORDS[COMP_CWORD]}"
|
local cur="${COMP_WORDS[COMP_CWORD]}"
|
||||||
local prev="${COMP_WORDS[COMP_CWORD-1]}"
|
local prev="${COMP_WORDS[COMP_CWORD-1]}"
|
||||||
|
|
||||||
if [ $COMP_CWORD -eq 2 ]
|
if [[ "$COMP_CWORD" -eq 2 ]]; then
|
||||||
then
|
_complete_collects ${cur}
|
||||||
_complete_collects ${cur}
|
else
|
||||||
else
|
case "${prev}" in
|
||||||
case "${prev}" in
|
# specifying a particular collection
|
||||||
-l) # specifying a particular collection
|
"-l" ) _complete_collects "$cur" ;;
|
||||||
_complete_collects ${cur}
|
* ) _filedir ;;
|
||||||
;;
|
esac
|
||||||
*)
|
fi
|
||||||
_filedir
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_raco()
|
_raco() {
|
||||||
{
|
COMPREPLY=()
|
||||||
COMPREPLY=()
|
local cur="${COMP_WORDS[COMP_CWORD]}"
|
||||||
local cur="${COMP_WORDS[COMP_CWORD]}"
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Complete the arguments to some of the basic commands.
|
# Complete the arguments to some of the basic commands.
|
||||||
#
|
#
|
||||||
local makeopts="--disable-inline --no-deps -p --prefix --no-prim -v -vv --help -h"
|
local makeopts="--disable-inline --no-deps -p --prefix --no-prim -v -vv --help -h"
|
||||||
|
|
||||||
if [ $COMP_CWORD -eq 1 ]; then
|
if [[ "$COMP_CWORD" -eq 1 ]]; then
|
||||||
# removing the empty string on the next line breaks things. such as my brain.
|
# removing the empty string on the next line breaks things. such as my brain.
|
||||||
_raco_cmds=$( echo '' 'help' ; for x in `${_racket_cmd} -e '(begin (require raco/all-tools) (for ([(k v) (all-tools)]) (printf "~a\n" k)))'` ; do echo ${x} ; done )
|
_raco_cmds="$(
|
||||||
COMPREPLY=($(compgen -W "${_raco_cmds}" -- ${cur}))
|
echo "help"
|
||||||
elif [ $COMP_CWORD -ge 2 ]; then
|
$_racket_cmd -e '(begin (require raco/all-tools)
|
||||||
# Here we'll handle the main raco commands
|
(for ([(k v) (all-tools)]) (printf "~a\n" k)))')"
|
||||||
local prev="${COMP_WORDS[1]}"
|
COMPREPLY=($(compgen -W "$_raco_cmds" -- "$cur"))
|
||||||
case "${prev}" in
|
elif [[ "$COMP_CWORD" -ge 2 ]]; then
|
||||||
make)
|
# Here we'll handle the main raco commands
|
||||||
case "${cur}" in
|
local prev="${COMP_WORDS[1]}"
|
||||||
-*)
|
case "$prev" in
|
||||||
COMPREPLY=( $(compgen -W "${makeopts}" -- ${cur}) )
|
"make" )
|
||||||
;;
|
case "$cur" in
|
||||||
*)
|
"-"* ) COMPREPLY=( $(compgen -W "$makeopts" -- "$cur") ) ;;
|
||||||
_filedir
|
* ) _filedir ;;
|
||||||
;;
|
esac ;;
|
||||||
esac
|
"planet" ) _raco_planet ;;
|
||||||
;;
|
"help" ) _raco_help ;;
|
||||||
planet)
|
"setup" ) _raco_setup ;;
|
||||||
_raco_planet
|
* ) _filedir ;;
|
||||||
;;
|
esac
|
||||||
help)
|
else
|
||||||
_raco_help
|
_filedir
|
||||||
;;
|
fi
|
||||||
setup)
|
|
||||||
_raco_setup
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
_filedir
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
else
|
|
||||||
_filedir
|
|
||||||
fi
|
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
complete -F _raco raco
|
complete -F _raco raco
|
||||||
|
|
Loading…
Reference in New Issue
Block a user