/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 bzrlib/plugins/bash_completion/bashcomp.py

  • Committer: Parth Malwankar
  • Date: 2010-07-08 09:11:44 UTC
  • mto: This revision was merged to the branch mainline in revision 5339.
  • Revision ID: parth.malwankar@gmail.com-20100708091144-1a1kqnah1fg1yrcx
re-install lazy re compile for failing test.

Show diffs side-by-side

added added

removed removed

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