/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: Jelmer Vernooij
  • Date: 2018-02-18 21:42:57 UTC
  • mto: This revision was merged to the branch mainline in revision 6859.
  • Revision ID: jelmer@jelmer.uk-20180218214257-jpevutp1wa30tz3v
Update TODO to reference Breezy, not Bazaar.

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
 
19
21
from ... import (
20
22
    cmdline,
21
23
    commands,
24
26
    option,
25
27
    plugin,
26
28
)
 
29
from ...sixish import (
 
30
    text_type,
 
31
    )
27
32
import breezy
28
33
import re
29
34
import sys
55
60
shopt -s progcomp
56
61
%(function)s
57
62
complete -F %(function_name)s -o default brz
58
 
""" % {
 
63
"""     % {
59
64
            "function_name": self.function_name,
60
65
            "function": self.function(),
61
66
            "brz_version": self.brz_version(),
65
70
        return ("""\
66
71
%(function_name)s ()
67
72
{
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
 
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
111
116
%(debug)s
112
 
    cmdOpts=( )
113
 
    optEnums=( )
114
 
    fixedWords=( )
115
 
    case $cmd in
 
117
        cmdOpts=( )
 
118
        optEnums=( )
 
119
        fixedWords=( )
 
120
        case $cmd in
116
121
%(cases)s\
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
 
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
154
159
}
155
 
""" % {
 
160
"""     % {
156
161
            "cmds": self.command_names(),
157
162
            "function_name": self.function_name,
158
163
            "cases": self.command_cases(),
169
174
            return ''
170
175
        else:
171
176
            return (r"""
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'
 
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'
182
187
""")
183
188
 
184
189
    def brz_version(self):
283
288
    def __cmp__(self, other):
284
289
        return cmp(self.name, other.name)
285
290
 
286
 
    def __lt__(self, other):
287
 
        return self.name < other.name
288
 
 
289
291
 
290
292
class DataCollector(object):
291
293
 
298
300
            self.selected_plugins = None
299
301
        else:
300
302
            self.selected_plugins = {x.replace('-', '_')
301
 
                                     for x in selected_plugins}
 
303
                                         for x in selected_plugins}
302
304
 
303
305
    def collect(self):
304
306
        self.global_options()
332
334
        plugin_name = cmd.plugin_name()
333
335
        if plugin_name is not None:
334
336
            if (self.selected_plugins is not None and
335
 
                    plugin not in self.selected_plugins):
 
337
                plugin not in self.selected_plugins):
336
338
                return None
337
339
            plugin_data = self.data.plugins.get(plugin_name)
338
340
            if plugin_data is None:
347
349
        # ones while maintaining the actual command name unchanged.
348
350
        cmd_data.aliases.extend(cmd.aliases)
349
351
        cmd_data.aliases.extend(sorted([useralias
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]))
 
352
            for cmdalias in cmd_data.aliases
 
353
            if cmdalias in self.user_aliases
 
354
            for useralias in self.user_aliases[cmdalias]
 
355
            if useralias not in cmd_data.aliases]))
354
356
 
355
357
        opts = cmd.options()
356
358
        for optname, opt in sorted(opts.items()):
358
360
 
359
361
        if 'help' == name or 'help' in cmd.aliases:
360
362
            cmd_data.fixed_words = ('($cmds %s)' %
361
 
                                    " ".join(sorted(help_topics.topic_registry.keys())))
 
363
                " ".join(sorted(help_topics.topic_registry.keys())))
362
364
 
363
365
        return cmd_data
364
366
 
365
367
    def option(self, opt):
366
368
        optswitches = {}
367
 
        parser = option.get_optparser([opt])
 
369
        parser = option.get_optparser({opt.name: opt})
368
370
        parser = self.wrap_parser(optswitches, parser)
369
371
        optswitches.clear()
370
372
        opt.add_option(parser, opt.short_name())
389
391
 
390
392
    def wrap_parser(self, optswitches, parser):
391
393
        orig_add_option_group = parser.add_option_group
392
 
 
393
394
        def tweaked_add_option_group(*opts, **attrs):
394
395
            return self.wrap_container(optswitches,
395
 
                                       orig_add_option_group(*opts, **attrs))
 
396
                orig_add_option_group(*opts, **attrs))
396
397
        parser.add_option_group = tweaked_add_option_group
397
398
        return self.wrap_container(optswitches, parser)
398
399
 
400
401
def bash_completion_function(out, function_name="_brz", function_only=False,
401
402
                             debug=False,
402
403
                             no_plugins=False, selected_plugins=None):
403
 
    dc = DataCollector(no_plugins=no_plugins,
404
 
                       selected_plugins=selected_plugins)
 
404
    dc = DataCollector(no_plugins=no_plugins, selected_plugins=selected_plugins)
405
405
    data = dc.collect()
406
406
    cg = BashCodeGen(data, function_name=function_name, debug=debug)
407
407
    if function_only:
417
417
    This command generates a shell function which can be used by bash to
418
418
    automatically complete the currently typed command when the user presses
419
419
    the completion key (usually tab).
420
 
 
 
420
    
421
421
    Commonly used like this:
422
422
        eval "`brz bash-completion`"
423
423
    """
424
424
 
425
425
    takes_options = [
426
 
        option.Option("function-name", short_name="f", type=str, argname="name",
427
 
                      help="Name of the generated function (default: _brz)"),
 
426
        option.Option("function-name", short_name="f", type=text_type, argname="name",
 
427
               help="Name of the generated function (default: _brz)"),
428
428
        option.Option("function-only", short_name="o", type=None,
429
 
                      help="Generate only the shell function, don't enable it"),
 
429
               help="Generate only the shell function, don't enable it"),
430
430
        option.Option("debug", type=None, hidden=True,
431
 
                      help="Enable shell code useful for debugging"),
432
 
        option.ListOption("plugin", type=str, argname="name",
433
 
                          # param_name="selected_plugins", # doesn't work, bug #387117
434
 
                          help="Enable completions for the selected plugin"
435
 
                          + " (default: all plugins)"),
 
431
               help="Enable shell code useful for debugging"),
 
432
        option.ListOption("plugin", type=text_type, argname="name",
 
433
                # param_name="selected_plugins", # doesn't work, bug #387117
 
434
                help="Enable completions for the selected plugin"
 
435
                + " (default: all plugins)"),
436
436
        ]
437
437
 
438
438
    def run(self, **kwargs):