add etc
This commit is contained in:
1
etc/Makefile.am
Normal file
1
etc/Makefile.am
Normal file
@@ -0,0 +1 @@
|
||||
SUBDIRS = bash_completion.d
|
||||
13
etc/bash_completion.d/Makefile.am
Normal file
13
etc/bash_completion.d/Makefile.am
Normal file
@@ -0,0 +1,13 @@
|
||||
completiondir = $(sysconfdir)/bash_completion.d
|
||||
completion_DATA = rip
|
||||
|
||||
BUILT_SOURCES = rip
|
||||
CLEANFILES = rip
|
||||
|
||||
EXTRA_DIST = bash-compgen
|
||||
|
||||
ENTRY = morituri.rip.main.Rip
|
||||
|
||||
rip: bash-compgen $(top_srcdir)/morituri $(top_srcdir)/morituri/*
|
||||
PYTHONPATH=$(top_srcdir):$$PYTHONPATH $(srcdir)/bash-compgen \
|
||||
$(completion_DATA) $(ENTRY) > $@
|
||||
211
etc/bash_completion.d/bash-compgen
Executable file
211
etc/bash_completion.d/bash-compgen
Executable file
@@ -0,0 +1,211 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- Mode: Python -*-
|
||||
# vi:si:et:sw=4:sts=4:ts=4
|
||||
|
||||
# generate bash completion for all commands
|
||||
# first argument should be program name
|
||||
# second argument should be the main Command entry class's fully qualified name
|
||||
|
||||
import sys
|
||||
|
||||
def funcName(cmd):
|
||||
"""
|
||||
Generate a name for the given command by walking up the ancestry
|
||||
and seperating with underscore.
|
||||
"""
|
||||
l = [cmd.name]
|
||||
while cmd.parentCommand:
|
||||
cmd = cmd.parentCommand
|
||||
l.append(cmd.name)
|
||||
|
||||
l.reverse()
|
||||
return "_%s_complete_" % cmd.name + "_".join(l)
|
||||
|
||||
def generateOneCommand(cmd):
|
||||
function = funcName(cmd)
|
||||
commandList = cmd.subCommands.keys()
|
||||
commandList.sort()
|
||||
commands = '"' + " ".join(commandList) + '"'
|
||||
|
||||
# poking into private instance variables for optparse.Option is nasty,
|
||||
# but I see no alternative
|
||||
optionBooleanList = []
|
||||
optionValueList = []
|
||||
optionList = []
|
||||
for option in cmd.parser.option_list:
|
||||
optionList.extend(option._short_opts + option._long_opts)
|
||||
if not option.nargs:
|
||||
optionBooleanList.extend(option._short_opts + option._long_opts)
|
||||
else:
|
||||
optionValueList.extend(option._short_opts + option._long_opts)
|
||||
optionList.sort()
|
||||
options = '"' + " ".join(optionList) + '"'
|
||||
optionsBoolean = '"' + " ".join(optionBooleanList) + '"'
|
||||
optionsValue = '"' + " ".join(optionValueList) + '"'
|
||||
|
||||
name = cmd.name
|
||||
|
||||
return """
|
||||
%(function)s()
|
||||
{
|
||||
options=%(options)s
|
||||
optionsboolean=%(optionsBoolean)s
|
||||
optionsvalue=%(optionsValue)s
|
||||
commands=%(commands)s
|
||||
completed=false
|
||||
|
||||
debug "function %(function)s"
|
||||
debug "args '$@'"
|
||||
debug "ARG1 '$1'"
|
||||
debug "ARG2 '$2'"
|
||||
shift
|
||||
debug "after shift: args '$@'"
|
||||
debug "ARG1 '$1'"
|
||||
debug "ARG2 '$2'"
|
||||
|
||||
|
||||
while [[ "$completed" == "false" ]]
|
||||
do
|
||||
if [[ "$1" == -* ]]
|
||||
then
|
||||
# handle as argument
|
||||
debug "handling argument $#"
|
||||
# found will be set to true when the current argument fully matches
|
||||
# an option, causing us to swallow it
|
||||
found=false
|
||||
# first check for boolean options
|
||||
for option in $optionsboolean
|
||||
do
|
||||
debug "matching option $option to args $1"
|
||||
if [[ "$option" == "$1" ]]
|
||||
then
|
||||
debug "found full boolean option $option, eating"
|
||||
found=true
|
||||
shift
|
||||
fi
|
||||
done
|
||||
# then check for valued options
|
||||
if [[ "$found" == false ]]
|
||||
then
|
||||
for option in $optionsvalue
|
||||
do
|
||||
debug "matching option $option to args $1"
|
||||
if [[ "$option" == "$1" ]]
|
||||
then
|
||||
found=true
|
||||
if [[ $# -eq 1 ]]
|
||||
then
|
||||
# a valued option with no value
|
||||
# we can't complete this since we don't know what
|
||||
# values the option takes
|
||||
completed=true
|
||||
COMPREPLY=()
|
||||
else
|
||||
# eat option and its value
|
||||
shift 2
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
if [[ "$found" == false ]]
|
||||
then
|
||||
debug "completing argument"
|
||||
COMPREPLY=( $( compgen -W "$options" -- $1 ) )
|
||||
debug "COMPREPLY ${COMPREPLY[*]}"
|
||||
completed=true
|
||||
fi
|
||||
else
|
||||
# handle as command
|
||||
debug "handle as command"
|
||||
found=false
|
||||
if [[ $# -eq 0 ]]; then
|
||||
# completing this command
|
||||
COMPREPLY=( $( compgen -W "$commands" -- $1 ) )
|
||||
debug "command, COMPREPLY ${COMPREPLY[*]}"
|
||||
completed=true
|
||||
else
|
||||
for command in $commands
|
||||
do
|
||||
debug "matching arg $1 against command $command"
|
||||
if [[ "$command" == "$1" ]]
|
||||
then
|
||||
debug "found full command, delegating"
|
||||
# completing a subcommand, delegate
|
||||
debug "delegate, $# args, 1 is $1"
|
||||
%(function)s_$1 $@
|
||||
debug "delegated, COMPREPLY ${COMPREPLY[*]}"
|
||||
found=true
|
||||
fi
|
||||
done
|
||||
# if not found, we must still be wanting to complete the
|
||||
# current partial command
|
||||
if [[ "$found" == false ]]
|
||||
then
|
||||
COMPREPLY=( $( compgen -W "$commands" -- $1 ) )
|
||||
completed=true
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
debug "function %(function)s: COMPREPLY ${COMPREPLY[*]}"
|
||||
done
|
||||
|
||||
}
|
||||
""" % locals()
|
||||
|
||||
def generateSubCommands(cmd):
|
||||
snippets = []
|
||||
if cmd.subCommands:
|
||||
for subCommand in cmd.subCommands.values():
|
||||
snippets.extend(generateSubCommands(subCommand))
|
||||
snippets.append(generateOneCommand(cmd))
|
||||
return snippets
|
||||
|
||||
|
||||
def start():
|
||||
if len(sys.argv) != 3:
|
||||
sys.stderr.write('Usage: %s [program-name] [entry-class]\n')
|
||||
sys.exit(1)
|
||||
|
||||
name = sys.argv[1]
|
||||
entry = sys.argv[2]
|
||||
parts = entry.split('.')
|
||||
if len(parts) <= 1:
|
||||
sys.stderr.write(
|
||||
'The entry class should be a module-qualified Class.\n')
|
||||
sys.exit(1)
|
||||
module = ".".join(parts[:-1])
|
||||
command = "from %s import %s as EntryClass" % (module, parts[-1])
|
||||
exec command
|
||||
entry = EntryClass()
|
||||
print """#-*- mode: shell-script;-*-
|
||||
|
||||
# Programmed completion for bash to use %s
|
||||
|
||||
""" % name
|
||||
|
||||
print "\n".join(generateSubCommands(entry))
|
||||
|
||||
print """
|
||||
# helper debug function
|
||||
debug()
|
||||
{
|
||||
if [[ ! -z "$DEBUG" ]]
|
||||
then
|
||||
echo $@
|
||||
fi
|
||||
}
|
||||
|
||||
# main entry point
|
||||
# dispatches to a command-specific function, passing in the rest of the
|
||||
# command line as arguments, starting with the command name being called
|
||||
_%(name)s()
|
||||
{
|
||||
COMPREPLY=()
|
||||
# pass as a list, not as a single string
|
||||
_%(name)s_complete_%(name)s ${COMP_WORDS[*]}
|
||||
}
|
||||
|
||||
complete -F _%(name)s -o default %(name)s
|
||||
""" % locals()
|
||||
|
||||
start()
|
||||
Reference in New Issue
Block a user