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