1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3
4import subprocess
5import io
6import re
7import sys
8import os.path
9
10class Option:
11    def __init__(self, long_opt, short_opt):
12        self.long_opt = long_opt
13        self.short_opt = short_opt
14
15def get_all_options(cmd):
16    opt_pattern = re.compile(r'  (?:(-.), )?(--[^\s\[=]+)(\[)?')
17    proc = subprocess.Popen([cmd, "--help"], stdout=subprocess.PIPE)
18    stdoutdata, _ = proc.communicate()
19    cur_option = None
20    opts = {}
21    for line in io.StringIO(stdoutdata.decode('utf-8')):
22        match = opt_pattern.match(line)
23        if not match:
24            continue
25        long_opt = match.group(2)
26        short_opt = match.group(1)
27        opts[long_opt] = Option(long_opt, short_opt)
28
29    return opts
30
31def output_case(out, name, opts):
32    out.write('''\
33_{name}()
34{{
35    local cur prev split=false
36    COMPREPLY=()
37    COMP_WORDBREAKS=${{COMP_WORDBREAKS//=}}
38
39    cmd=${{COMP_WORDS[0]}}
40    _get_comp_words_by_ref cur prev
41'''.format(name=name))
42
43    # Complete option name.
44    out.write('''\
45    case $cur in
46        -*)
47            COMPREPLY=( $( compgen -W '\
48''')
49    for opt in opts.values():
50        out.write(opt.long_opt)
51        out.write(' ')
52
53    out.write('''\
54' -- "$cur" ) )
55            ;;
56''')
57    # If no option found for completion then complete with files.
58    out.write('''\
59        *)
60            _filedir
61            return 0
62    esac
63    return 0
64}}
65complete -F _{name} {name}
66'''.format(name=name))
67
68if __name__ == '__main__':
69    if len(sys.argv) < 2:
70        print("Generates bash_completion using `/path/to/cmd --help'")
71        print("Usage: make_bash_completion.py /path/to/cmd")
72        exit(1)
73    name = os.path.basename(sys.argv[1])
74    opts = get_all_options(sys.argv[1])
75    output_case(sys.stdout, name, opts)
76