/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/plugins/bash_completion/bashcomp.py

  • Committer: Breezy landing bot
  • Author(s): Colin Watson
  • Date: 2020-11-16 21:47:08 UTC
  • mfrom: (7521.1.1 remove-lp-workaround)
  • Revision ID: breezy.the.bot@gmail.com-20201116214708-jos209mgxi41oy15
Remove breezy.git workaround for bazaar.launchpad.net.

Merged from https://code.launchpad.net/~cjwatson/brz/remove-lp-workaround/+merge/393710

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#!/usr/bin/env python
 
1
#!/usr/bin/env python3
2
2
 
3
3
# Copyright (C) 2009, 2010 Canonical Ltd
4
4
#
16
16
# along with this program; if not, write to the Free Software
17
17
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
18
 
19
 
from __future__ import absolute_import
20
 
 
21
 
from bzrlib import (
 
19
from ... import (
22
20
    cmdline,
23
21
    commands,
24
22
    config,
26
24
    option,
27
25
    plugin,
28
26
)
29
 
import bzrlib
 
27
import breezy
30
28
import re
31
29
import sys
32
30
 
34
32
class BashCodeGen(object):
35
33
    """Generate a bash script for given completion data."""
36
34
 
37
 
    def __init__(self, data, function_name='_bzr', debug=False):
 
35
    def __init__(self, data, function_name='_brz', debug=False):
38
36
        self.data = data
39
37
        self.function_name = function_name
40
38
        self.debug = debug
41
39
 
42
40
    def script(self):
43
41
        return ("""\
44
 
# Programmable completion for the Bazaar-NG bzr command under bash.
 
42
# Programmable completion for the Breezy brz command under bash.
45
43
# Known to work with bash 2.05a as well as bash 4.1.2, and probably
46
44
# all versions in between as well.
47
45
 
52
50
# Generated using the bash_completion plugin.
53
51
# See https://launchpad.net/bzr-bash-completion for details.
54
52
 
55
 
# Commands and options of bzr %(bzr_version)s
 
53
# Commands and options of brz %(brz_version)s
56
54
 
57
55
shopt -s progcomp
58
56
%(function)s
59
 
complete -F %(function_name)s -o default bzr
60
 
"""     % {
 
57
complete -F %(function_name)s -o default brz
 
58
""" % {
61
59
            "function_name": self.function_name,
62
60
            "function": self.function(),
63
 
            "bzr_version": self.bzr_version(),
 
61
            "brz_version": self.brz_version(),
64
62
        })
65
63
 
66
64
    def function(self):
67
65
        return ("""\
68
66
%(function_name)s ()
69
67
{
70
 
        local cur cmds cmdIdx cmd cmdOpts fixedWords i globalOpts
71
 
        local curOpt optEnums
72
 
        local IFS=$' \\n'
73
 
 
74
 
        COMPREPLY=()
75
 
        cur=${COMP_WORDS[COMP_CWORD]}
76
 
 
77
 
        cmds='%(cmds)s'
78
 
        globalOpts=( %(global_options)s )
79
 
 
80
 
        # do ordinary expansion if we are anywhere after a -- argument
81
 
        for ((i = 1; i < COMP_CWORD; ++i)); do
82
 
                [[ ${COMP_WORDS[i]} == "--" ]] && return 0
83
 
        done
84
 
 
85
 
        # find the command; it's the first word not starting in -
86
 
        cmd=
87
 
        for ((cmdIdx = 1; cmdIdx < ${#COMP_WORDS[@]}; ++cmdIdx)); do
88
 
                if [[ ${COMP_WORDS[cmdIdx]} != -* ]]; then
89
 
                        cmd=${COMP_WORDS[cmdIdx]}
90
 
                        break
91
 
                fi
92
 
        done
93
 
 
94
 
        # complete command name if we are not already past the command
95
 
        if [[ $COMP_CWORD -le cmdIdx ]]; then
96
 
                COMPREPLY=( $( compgen -W "$cmds ${globalOpts[*]}" -- $cur ) )
97
 
                return 0
98
 
        fi
99
 
 
100
 
        # find the option for which we want to complete a value
101
 
        curOpt=
102
 
        if [[ $cur != -* ]] && [[ $COMP_CWORD -gt 1 ]]; then
103
 
                curOpt=${COMP_WORDS[COMP_CWORD - 1]}
104
 
                if [[ $curOpt == = ]]; then
105
 
                        curOpt=${COMP_WORDS[COMP_CWORD - 2]}
106
 
                elif [[ $cur == : ]]; then
107
 
                        cur=
108
 
                        curOpt="$curOpt:"
109
 
                elif [[ $curOpt == : ]]; then
110
 
                        curOpt=${COMP_WORDS[COMP_CWORD - 2]}:
111
 
                fi
112
 
        fi
 
68
    local cur cmds cmdIdx cmd cmdOpts fixedWords i globalOpts
 
69
    local curOpt optEnums
 
70
    local IFS=$' \\n'
 
71
 
 
72
    COMPREPLY=()
 
73
    cur=${COMP_WORDS[COMP_CWORD]}
 
74
 
 
75
    cmds='%(cmds)s'
 
76
    globalOpts=( %(global_options)s )
 
77
 
 
78
    # do ordinary expansion if we are anywhere after a -- argument
 
79
    for ((i = 1; i < COMP_CWORD; ++i)); do
 
80
        [[ ${COMP_WORDS[i]} == "--" ]] && return 0
 
81
    done
 
82
 
 
83
    # find the command; it's the first word not starting in -
 
84
    cmd=
 
85
    for ((cmdIdx = 1; cmdIdx < ${#COMP_WORDS[@]}; ++cmdIdx)); do
 
86
        if [[ ${COMP_WORDS[cmdIdx]} != -* ]]; then
 
87
            cmd=${COMP_WORDS[cmdIdx]}
 
88
            break
 
89
        fi
 
90
    done
 
91
 
 
92
    # complete command name if we are not already past the command
 
93
    if [[ $COMP_CWORD -le cmdIdx ]]; then
 
94
        COMPREPLY=( $( compgen -W "$cmds ${globalOpts[*]}" -- $cur ) )
 
95
        return 0
 
96
    fi
 
97
 
 
98
    # find the option for which we want to complete a value
 
99
    curOpt=
 
100
    if [[ $cur != -* ]] && [[ $COMP_CWORD -gt 1 ]]; then
 
101
        curOpt=${COMP_WORDS[COMP_CWORD - 1]}
 
102
        if [[ $curOpt == = ]]; then
 
103
            curOpt=${COMP_WORDS[COMP_CWORD - 2]}
 
104
        elif [[ $cur == : ]]; then
 
105
            cur=
 
106
            curOpt="$curOpt:"
 
107
        elif [[ $curOpt == : ]]; then
 
108
            curOpt=${COMP_WORDS[COMP_CWORD - 2]}:
 
109
        fi
 
110
    fi
113
111
%(debug)s
114
 
        cmdOpts=( )
115
 
        optEnums=( )
116
 
        fixedWords=( )
117
 
        case $cmd in
 
112
    cmdOpts=( )
 
113
    optEnums=( )
 
114
    fixedWords=( )
 
115
    case $cmd in
118
116
%(cases)s\
119
 
        *)
120
 
                cmdOpts=(--help -h)
121
 
                ;;
122
 
        esac
123
 
 
124
 
        IFS=$'\\n'
125
 
        if [[ ${#fixedWords[@]} -eq 0 ]] && [[ ${#optEnums[@]} -eq 0 ]] && [[ $cur != -* ]]; then
126
 
                case $curOpt in
127
 
                        tag:|*..tag:)
128
 
                                fixedWords=( $(bzr tags 2>/dev/null | sed 's/  *[^ ]*$//; s/ /\\\\\\\\ /g;') )
129
 
                                ;;
130
 
                esac
131
 
                case $cur in
132
 
                        [\\"\\']tag:*)
133
 
                                fixedWords=( $(bzr tags 2>/dev/null | sed 's/  *[^ ]*$//; s/^/tag:/') )
134
 
                                ;;
135
 
                        [\\"\\']*..tag:*)
136
 
                                fixedWords=( $(bzr tags 2>/dev/null | sed 's/  *[^ ]*$//') )
137
 
                                fixedWords=( $(for i in "${fixedWords[@]}"; do echo "${cur%%..tag:*}..tag:${i}"; done) )
138
 
                                ;;
139
 
                esac
140
 
        elif [[ $cur == = ]] && [[ ${#optEnums[@]} -gt 0 ]]; then
141
 
                # complete directly after "--option=", list all enum values
142
 
                COMPREPLY=( "${optEnums[@]}" )
143
 
                return 0
144
 
        else
145
 
                fixedWords=( "${cmdOpts[@]}"
146
 
                             "${globalOpts[@]}"
147
 
                             "${optEnums[@]}"
148
 
                             "${fixedWords[@]}" )
149
 
        fi
150
 
 
151
 
        if [[ ${#fixedWords[@]} -gt 0 ]]; then
152
 
                COMPREPLY=( $( compgen -W "${fixedWords[*]}" -- $cur ) )
153
 
        fi
154
 
 
155
 
        return 0
 
117
    *)
 
118
        cmdOpts=(--help -h)
 
119
        ;;
 
120
    esac
 
121
 
 
122
    IFS=$'\\n'
 
123
    if [[ ${#fixedWords[@]} -eq 0 ]] && [[ ${#optEnums[@]} -eq 0 ]] && [[ $cur != -* ]]; then
 
124
        case $curOpt in
 
125
            tag:|*..tag:)
 
126
                fixedWords=( $(brz tags 2>/dev/null | sed 's/  *[^ ]*$//; s/ /\\\\\\\\ /g;') )
 
127
                ;;
 
128
        esac
 
129
        case $cur in
 
130
            [\\"\\']tag:*)
 
131
                fixedWords=( $(brz tags 2>/dev/null | sed 's/  *[^ ]*$//; s/^/tag:/') )
 
132
                ;;
 
133
            [\\"\\']*..tag:*)
 
134
                fixedWords=( $(brz tags 2>/dev/null | sed 's/  *[^ ]*$//') )
 
135
                fixedWords=( $(for i in "${fixedWords[@]}"; do echo "${cur%%..tag:*}..tag:${i}"; done) )
 
136
                ;;
 
137
        esac
 
138
    elif [[ $cur == = ]] && [[ ${#optEnums[@]} -gt 0 ]]; then
 
139
        # complete directly after "--option=", list all enum values
 
140
        COMPREPLY=( "${optEnums[@]}" )
 
141
        return 0
 
142
    else
 
143
        fixedWords=( "${cmdOpts[@]}"
 
144
                     "${globalOpts[@]}"
 
145
                     "${optEnums[@]}"
 
146
                     "${fixedWords[@]}" )
 
147
    fi
 
148
 
 
149
    if [[ ${#fixedWords[@]} -gt 0 ]]; then
 
150
        COMPREPLY=( $( compgen -W "${fixedWords[*]}" -- $cur ) )
 
151
    fi
 
152
 
 
153
    return 0
156
154
}
157
 
"""     % {
 
155
""" % {
158
156
            "cmds": self.command_names(),
159
157
            "function_name": self.function_name,
160
158
            "cases": self.command_cases(),
171
169
            return ''
172
170
        else:
173
171
            return (r"""
174
 
        # Debugging code enabled using the --debug command line switch.
175
 
        # Will dump some variables to the top portion of the terminal.
176
 
        echo -ne '\e[s\e[H'
177
 
        for (( i=0; i < ${#COMP_WORDS[@]}; ++i)); do
178
 
                echo "\$COMP_WORDS[$i]='${COMP_WORDS[i]}'"$'\e[K'
179
 
        done
180
 
        for i in COMP_CWORD COMP_LINE COMP_POINT COMP_TYPE COMP_KEY cur curOpt; do
181
 
                echo "\$${i}=\"${!i}\""$'\e[K'
182
 
        done
183
 
        echo -ne '---\e[K\e[u'
 
172
    # Debugging code enabled using the --debug command line switch.
 
173
    # Will dump some variables to the top portion of the terminal.
 
174
    echo -ne '\e[s\e[H'
 
175
    for (( i=0; i < ${#COMP_WORDS[@]}; ++i)); do
 
176
        echo "\$COMP_WORDS[$i]='${COMP_WORDS[i]}'"$'\e[K'
 
177
    done
 
178
    for i in COMP_CWORD COMP_LINE COMP_POINT COMP_TYPE COMP_KEY cur curOpt; do
 
179
        echo "\$${i}=\"${!i}\""$'\e[K'
 
180
    done
 
181
    echo -ne '---\e[K\e[u'
184
182
""")
185
183
 
186
 
    def bzr_version(self):
187
 
        bzr_version = bzrlib.version_string
 
184
    def brz_version(self):
 
185
        brz_version = breezy.version_string
188
186
        if not self.data.plugins:
189
 
            bzr_version += "."
 
187
            brz_version += "."
190
188
        else:
191
 
            bzr_version += " and the following plugins:"
192
 
            for name, plugin in sorted(self.data.plugins.iteritems()):
193
 
                bzr_version += "\n# %s" % plugin
194
 
        return bzr_version
 
189
            brz_version += " and the following plugins:"
 
190
            for name, plugin in sorted(self.data.plugins.items()):
 
191
                brz_version += "\n# %s" % plugin
 
192
        return brz_version
195
193
 
196
194
    def global_options(self):
197
195
        return " ".join(sorted(self.data.global_options))
260
258
    def __init__(self, name, version=None):
261
259
        if version is None:
262
260
            try:
263
 
                version = bzrlib.plugin.plugins()[name].__version__
 
261
                version = breezy.plugin.plugins()[name].__version__
264
262
            except:
265
263
                version = 'unknown'
266
264
        self.name = name
285
283
    def __cmp__(self, other):
286
284
        return cmp(self.name, other.name)
287
285
 
 
286
    def __lt__(self, other):
 
287
        return self.name < other.name
 
288
 
288
289
 
289
290
class DataCollector(object):
290
291
 
296
297
        elif selected_plugins is None:
297
298
            self.selected_plugins = None
298
299
        else:
299
 
            self.selected_plugins = set([x.replace('-', '_')
300
 
                                         for x in selected_plugins])
 
300
            self.selected_plugins = {x.replace('-', '_')
 
301
                                     for x in selected_plugins}
301
302
 
302
303
    def collect(self):
303
304
        self.global_options()
314
315
                self.data.global_options.add(short)
315
316
 
316
317
    def aliases(self):
317
 
        for alias, expansion in config.GlobalConfig().get_aliases().iteritems():
 
318
        for alias, expansion in config.GlobalConfig().get_aliases().items():
318
319
            for token in cmdline.split(expansion):
319
320
                if not token.startswith("-"):
320
321
                    self.user_aliases.setdefault(token, set()).add(alias)
331
332
        plugin_name = cmd.plugin_name()
332
333
        if plugin_name is not None:
333
334
            if (self.selected_plugins is not None and
334
 
                plugin not in self.selected_plugins):
 
335
                    plugin not in self.selected_plugins):
335
336
                return None
336
337
            plugin_data = self.data.plugins.get(plugin_name)
337
338
            if plugin_data is None:
346
347
        # ones while maintaining the actual command name unchanged.
347
348
        cmd_data.aliases.extend(cmd.aliases)
348
349
        cmd_data.aliases.extend(sorted([useralias
349
 
            for cmdalias in cmd_data.aliases
350
 
            if cmdalias in self.user_aliases
351
 
            for useralias in self.user_aliases[cmdalias]
352
 
            if useralias not in cmd_data.aliases]))
 
350
                                        for cmdalias in cmd_data.aliases
 
351
                                        if cmdalias in self.user_aliases
 
352
                                        for useralias in self.user_aliases[cmdalias]
 
353
                                        if useralias not in cmd_data.aliases]))
353
354
 
354
355
        opts = cmd.options()
355
 
        for optname, opt in sorted(opts.iteritems()):
 
356
        for optname, opt in sorted(opts.items()):
356
357
            cmd_data.options.extend(self.option(opt))
357
358
 
358
359
        if 'help' == name or 'help' in cmd.aliases:
359
360
            cmd_data.fixed_words = ('($cmds %s)' %
360
 
                " ".join(sorted(help_topics.topic_registry.keys())))
 
361
                                    " ".join(sorted(help_topics.topic_registry.keys())))
361
362
 
362
363
        return cmd_data
363
364
 
364
365
    def option(self, opt):
365
366
        optswitches = {}
366
 
        parser = option.get_optparser({opt.name: opt})
 
367
        parser = option.get_optparser([opt])
367
368
        parser = self.wrap_parser(optswitches, parser)
368
369
        optswitches.clear()
369
370
        opt.add_option(parser, opt.short_name())
373
374
            if enum_data:
374
375
                try:
375
376
                    enum_data.registry_keys = opt.registry.keys()
376
 
                except ImportError, e:
 
377
                except ImportError as e:
377
378
                    enum_data.error_messages.append(
378
379
                        "ERROR getting registry keys for '--%s': %s"
379
380
                        % (opt.name, str(e).split('\n')[0]))
388
389
 
389
390
    def wrap_parser(self, optswitches, parser):
390
391
        orig_add_option_group = parser.add_option_group
 
392
 
391
393
        def tweaked_add_option_group(*opts, **attrs):
392
394
            return self.wrap_container(optswitches,
393
 
                orig_add_option_group(*opts, **attrs))
 
395
                                       orig_add_option_group(*opts, **attrs))
394
396
        parser.add_option_group = tweaked_add_option_group
395
397
        return self.wrap_container(optswitches, parser)
396
398
 
397
399
 
398
 
def bash_completion_function(out, function_name="_bzr", function_only=False,
 
400
def bash_completion_function(out, function_name="_brz", function_only=False,
399
401
                             debug=False,
400
402
                             no_plugins=False, selected_plugins=None):
401
 
    dc = DataCollector(no_plugins=no_plugins, selected_plugins=selected_plugins)
 
403
    dc = DataCollector(no_plugins=no_plugins,
 
404
                       selected_plugins=selected_plugins)
402
405
    data = dc.collect()
403
406
    cg = BashCodeGen(data, function_name=function_name, debug=debug)
404
407
    if function_only:
414
417
    This command generates a shell function which can be used by bash to
415
418
    automatically complete the currently typed command when the user presses
416
419
    the completion key (usually tab).
417
 
    
 
420
 
418
421
    Commonly used like this:
419
 
        eval "`bzr bash-completion`"
 
422
        eval "`brz bash-completion`"
420
423
    """
421
424
 
422
425
    takes_options = [
423
426
        option.Option("function-name", short_name="f", type=str, argname="name",
424
 
               help="Name of the generated function (default: _bzr)"),
 
427
                      help="Name of the generated function (default: _brz)"),
425
428
        option.Option("function-only", short_name="o", type=None,
426
 
               help="Generate only the shell function, don't enable it"),
 
429
                      help="Generate only the shell function, don't enable it"),
427
430
        option.Option("debug", type=None, hidden=True,
428
 
               help="Enable shell code useful for debugging"),
 
431
                      help="Enable shell code useful for debugging"),
429
432
        option.ListOption("plugin", type=str, argname="name",
430
 
                # param_name="selected_plugins", # doesn't work, bug #387117
431
 
                help="Enable completions for the selected plugin"
432
 
                + " (default: all plugins)"),
 
433
                          # param_name="selected_plugins", # doesn't work, bug #387117
 
434
                          help="Enable completions for the selected plugin"
 
435
                          + " (default: all plugins)"),
433
436
        ]
434
437
 
435
438
    def run(self, **kwargs):
455
458
 
456
459
    parser = optparse.OptionParser(usage="%prog [-f NAME] [-o]")
457
460
    parser.add_option("--function-name", "-f", metavar="NAME",
458
 
                      help="Name of the generated function (default: _bzr)")
 
461
                      help="Name of the generated function (default: _brz)")
459
462
    parser.add_option("--function-only", "-o", action="store_true",
460
463
                      help="Generate only the shell function, don't enable it")
461
464
    parser.add_option("--debug", action="store_true",
462
465
                      help=optparse.SUPPRESS_HELP)
463
466
    parser.add_option("--no-plugins", action="store_true",
464
 
                      help="Don't load any bzr plugins")
 
467
                      help="Don't load any brz plugins")
465
468
    parser.add_option("--plugin", metavar="NAME", type="string",
466
469
                      dest="selected_plugins", default=[],
467
470
                      action="callback", callback=plugin_callback,
471
474
    if args:
472
475
        parser.error("script does not take positional arguments")
473
476
    kwargs = dict()
474
 
    for name, value in opts.__dict__.iteritems():
 
477
    for name, value in opts.__dict__.items():
475
478
        if value is not None:
476
479
            kwargs[name] = value
477
480