3
# Copyright (C) 2009, 2010 Canonical Ltd
5
# This file is part of bzr-bash-completion
7
# bzr-bash-completion free software: you can redistribute it and/or
8
# modify it under the terms of the GNU General Public License as
9
# published by the Free Software Foundation, either version 2 of the
10
# License, or (at your option) any later version.
12
# bzr-bash-completion is distributed in the hope that it will be
13
# useful, but WITHOUT ANY WARRANTY; without even the implied warranty
14
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
# General Public License for more details.
17
# You should have received a copy of the GNU General Public License
18
# along with this program. If not, see <http://www.gnu.org/licenses/>.
20
from meta import __version__
32
# Programmable completion for the Bazaar-NG bzr command under bash.
33
# Known to work with bash 2.05a as well as bash 4.1.2, and probably
34
# all versions in between as well.
36
# Based originally on the svn bash completition script.
37
# Customized by Sven Wilhelm/Icecrash.com
38
# Adjusted for automatic generation by Martin von Gagern
40
# Generated using the bzr-bash-completion plugin version %(version)s.
41
# See https://launchpad.net/bzr-bash-completion for details.
43
# Commands and options of bzr %(bzr_version)s
50
local cur cmds cmdIdx cmd cmdOpts fixedWords i globalOpts
54
cur=${COMP_WORDS[COMP_CWORD]}
57
globalOpts='%(global_options)s'
59
# do ordinary expansion if we are anywhere after a -- argument
60
for ((i = 1; i < COMP_CWORD; ++i)); do
61
[[ ${COMP_WORDS[i]} == "--" ]] && return 0
64
# find the command; it's the first word not starting in -
66
for ((cmdIdx = 1; cmdIdx < ${#COMP_WORDS[@]}; ++cmdIdx)); do
67
if [[ ${COMP_WORDS[cmdIdx]} != -* ]]; then
68
cmd=${COMP_WORDS[cmdIdx]}
73
# complete command name if we are not already past the command
74
if [[ $COMP_CWORD -le cmdIdx ]]; then
75
COMPREPLY=( $( compgen -W "$cmds $globalOpts" -- $cur ) )
79
# find the option for which we want to complete a value
81
if [[ $cur != -* ]] && [[ $COMP_CWORD -gt 1 ]]; then
82
curOpt=${COMP_WORDS[COMP_CWORD - 1]}
83
if [[ $curOpt == = ]]; then
84
curOpt=${COMP_WORDS[COMP_CWORD - 2]}
98
# if not typing an option, and if we don't know all the
99
# possible non-option arguments for the current command,
100
# then fallback on ordinary filename expansion
101
if [[ -z $fixedWords ]] && [[ -z $optEnums ]] && [[ $cur != -* ]]; then
105
if [[ $cur == = ]] && [[ -n $optEnums ]]; then
106
# complete directly after "--option=", list all enum values
107
COMPREPLY=( $optEnums )
109
fixedWords="$cmdOpts $globalOpts $optEnums $fixedWords"
110
COMPREPLY=( $( compgen -W "$fixedWords" -- $cur ) )
117
complete -F %(function_name)s -o default bzr
120
# Debugging code enabled using the --debug command line switch.
121
# Will dump some variables to the top portion of the terminal.
123
for (( i=0; i < ${#COMP_WORDS[@]}; ++i)); do
124
echo "\$COMP_WORDS[$i]='${COMP_WORDS[i]}'"$'\e[K'
126
for i in COMP_CWORD COMP_LINE COMP_POINT COMP_TYPE COMP_KEY cur curOpt; do
127
echo "\$${i}=\"${!i}\""$'\e[K'
129
echo -ne '---\e[K\e[u'
132
def wrap_container(list, parser):
133
def tweaked_add_option(*opts, **attrs):
135
parser.add_option = tweaked_add_option
138
def wrap_parser(list, parser):
139
orig_add_option_group = parser.add_option_group
140
def tweaked_add_option_group(*opts, **attrs):
141
return wrap_container(list, orig_add_option_group(*opts, **attrs))
142
parser.add_option_group = tweaked_add_option_group
143
return wrap_container(list, parser)
145
def bash_completion_function(out, function_name="_bzr", function_only=False,
147
no_plugins=False, selected_plugins=None):
153
selected_plugins = set([x.replace('-', '_') for x in selected_plugins])
155
selected_plugins = None
157
re_switch = re.compile(r'\n(--[A-Za-z0-9-_]+)(?:, (-\S))?\s')
158
help_text = help_topics.topic_registry.get_detail('global-options')
159
global_options = set()
160
for long, short in re_switch.findall(help_text):
161
global_options.add(long)
163
global_options.add(short)
164
global_options = " ".join(sorted(global_options))
166
user_aliases = {} # dict from cmd name to set of user-defined alias names
167
for alias, expansion in config.GlobalConfig().get_aliases().iteritems():
168
for token in commands.shlex_split_unicode(expansion):
169
if not token.startswith("-"):
170
user_aliases.setdefault(token, set()).add(alias)
173
all_cmds = sorted(commands.all_command_names())
174
for cmdname in all_cmds:
175
cmd = commands.get_cmd_object(cmdname)
177
# Find all aliases to the command; both cmd-defined and user-defined.
178
# We assume a user won't override one command with a different one,
179
# but will choose completely new names or add options to existing
180
# ones while maintaining the actual command name unchanged.
182
aliases.extend(cmd.aliases)
183
aliases.extend(sorted([alias
185
if name in user_aliases
186
for alias in user_aliases[name]
187
if alias not in aliases]))
188
cases += "\t%s)\n" % "|".join(aliases)
190
plugin = cmd.plugin_name()
191
if plugin is not None:
192
if selected_plugins is not None and plugin not in selected_plugins:
195
cases += "\t\t# plugin \"%s\"\n" % plugin
200
for optname in sorted(cmd.options()):
203
parser = option.get_optparser({optname: opt})
204
parser = wrap_parser(optswitches, parser)
206
opt.add_option(parser, opt.short_name())
207
if isinstance(opt, option.RegistryOption) and opt.enum_switch:
208
enum_switch = '--%s' % optname
209
keys = opt.registry.keys()
210
if enum_switch in optswitches and keys:
211
optswitches.remove(enum_switch)
213
optswitches.append('%s=%s' % (enum_switch, key))
214
enums.append("%s) optEnums='%s' ;;"
215
% (enum_switch, ' '.join(keys)))
216
switches.extend(optswitches)
217
if 'help' == cmdname or 'help' in cmd.aliases:
218
fixedWords = " ".join(sorted(help_topics.topic_registry.keys()))
219
fixedWords = '"$cmds %s"' % fixedWords
221
cases += "\t\tcmdOpts='" + " ".join(switches) + "'\n"
223
if isinstance(fixedWords, list):
224
fixedWords = "'" + join(fixedWords) + "'"
225
cases += "\t\tfixedWords=" + fixedWords + "\n"
227
cases += "\t\tcase $curOpt in\n\t\t\t"
228
cases += "\n\t\t\t".join(enums)
229
cases += "\n\t\tesac\n"
232
bzr_version = bzrlib.version_string
236
bzr_version += " and the following plugins:"
237
for plugin in sorted(plugins):
238
pv = bzrlib.plugin.plugins()[plugin].__version__
243
bzr_version += "\n# %s%s" % (plugin, pv)
248
template = head + fun + tail
249
out.write(template % {"cmds": " ".join(cmds),
251
"function_name": function_name,
252
"version": __version__,
253
"global_options": global_options,
254
"debug": debug_output if debug else "",
255
"bzr_version": bzr_version,
258
if __name__ == '__main__':
263
from meta import __version__
265
def plugin_callback(option, opt, value, parser):
266
values = parser.values.selected_plugins
272
parser = optparse.OptionParser(usage="%prog [-f NAME] [-o]",
273
version="%%prog %s" % __version__)
274
parser.add_option("--function-name", "-f", metavar="NAME",
275
help="Name of the generated function (default: _bzr)")
276
parser.add_option("--function-only", "-o", action="store_true",
277
help="Generate only the shell function, don't enable it")
278
parser.add_option("--debug", action="store_true",
279
help=optparse.SUPPRESS_HELP)
280
parser.add_option("--no-plugins", action="store_true",
281
help="Don't load any bzr plugins")
282
parser.add_option("--plugin", metavar="NAME", type="string",
283
dest="selected_plugins", default=[],
284
action="callback", callback=plugin_callback,
285
help="Enable completions for the selected plugin"
286
+ " (default: all plugins)")
287
(opts, args) = parser.parse_args()
289
parser.error("script does not take positional arguments")
291
for name, value in opts.__dict__.iteritems():
292
if value is not None:
295
locale.setlocale(locale.LC_ALL, '')
296
if not kwargs.get('no_plugins', False):
297
plugin.load_plugins()
298
commands.install_bzr_command_hooks()
299
bash_completion_function(sys.stdout, **kwargs)