12c593315Sopenharmony_ci#!/usr/bin/env python3 22c593315Sopenharmony_ci# -*- coding: utf-8 -*- 32c593315Sopenharmony_ci 42c593315Sopenharmony_ciimport subprocess 52c593315Sopenharmony_ciimport io 62c593315Sopenharmony_ciimport re 72c593315Sopenharmony_ciimport sys 82c593315Sopenharmony_ciimport os.path 92c593315Sopenharmony_ci 102c593315Sopenharmony_ciclass Option: 112c593315Sopenharmony_ci def __init__(self, long_opt, short_opt): 122c593315Sopenharmony_ci self.long_opt = long_opt 132c593315Sopenharmony_ci self.short_opt = short_opt 142c593315Sopenharmony_ci 152c593315Sopenharmony_cidef get_all_options(cmd): 162c593315Sopenharmony_ci opt_pattern = re.compile(r' (?:(-.), )?(--[^\s\[=]+)(\[)?') 172c593315Sopenharmony_ci proc = subprocess.Popen([cmd, "--help"], stdout=subprocess.PIPE) 182c593315Sopenharmony_ci stdoutdata, _ = proc.communicate() 192c593315Sopenharmony_ci cur_option = None 202c593315Sopenharmony_ci opts = {} 212c593315Sopenharmony_ci for line in io.StringIO(stdoutdata.decode('utf-8')): 222c593315Sopenharmony_ci match = opt_pattern.match(line) 232c593315Sopenharmony_ci if not match: 242c593315Sopenharmony_ci continue 252c593315Sopenharmony_ci long_opt = match.group(2) 262c593315Sopenharmony_ci short_opt = match.group(1) 272c593315Sopenharmony_ci opts[long_opt] = Option(long_opt, short_opt) 282c593315Sopenharmony_ci 292c593315Sopenharmony_ci return opts 302c593315Sopenharmony_ci 312c593315Sopenharmony_cidef output_case(out, name, opts): 322c593315Sopenharmony_ci out.write('''\ 332c593315Sopenharmony_ci_{name}() 342c593315Sopenharmony_ci{{ 352c593315Sopenharmony_ci local cur prev split=false 362c593315Sopenharmony_ci COMPREPLY=() 372c593315Sopenharmony_ci COMP_WORDBREAKS=${{COMP_WORDBREAKS//=}} 382c593315Sopenharmony_ci 392c593315Sopenharmony_ci cmd=${{COMP_WORDS[0]}} 402c593315Sopenharmony_ci _get_comp_words_by_ref cur prev 412c593315Sopenharmony_ci'''.format(name=name)) 422c593315Sopenharmony_ci 432c593315Sopenharmony_ci # Complete option name. 442c593315Sopenharmony_ci out.write('''\ 452c593315Sopenharmony_ci case $cur in 462c593315Sopenharmony_ci -*) 472c593315Sopenharmony_ci COMPREPLY=( $( compgen -W '\ 482c593315Sopenharmony_ci''') 492c593315Sopenharmony_ci for opt in opts.values(): 502c593315Sopenharmony_ci out.write(opt.long_opt) 512c593315Sopenharmony_ci out.write(' ') 522c593315Sopenharmony_ci 532c593315Sopenharmony_ci out.write('''\ 542c593315Sopenharmony_ci' -- "$cur" ) ) 552c593315Sopenharmony_ci ;; 562c593315Sopenharmony_ci''') 572c593315Sopenharmony_ci # If no option found for completion then complete with files. 582c593315Sopenharmony_ci out.write('''\ 592c593315Sopenharmony_ci *) 602c593315Sopenharmony_ci _filedir 612c593315Sopenharmony_ci return 0 622c593315Sopenharmony_ci esac 632c593315Sopenharmony_ci return 0 642c593315Sopenharmony_ci}} 652c593315Sopenharmony_cicomplete -F _{name} {name} 662c593315Sopenharmony_ci'''.format(name=name)) 672c593315Sopenharmony_ci 682c593315Sopenharmony_ciif __name__ == '__main__': 692c593315Sopenharmony_ci if len(sys.argv) < 2: 702c593315Sopenharmony_ci print("Generates bash_completion using `/path/to/cmd --help'") 712c593315Sopenharmony_ci print("Usage: make_bash_completion.py /path/to/cmd") 722c593315Sopenharmony_ci exit(1) 732c593315Sopenharmony_ci name = os.path.basename(sys.argv[1]) 742c593315Sopenharmony_ci opts = get_all_options(sys.argv[1]) 752c593315Sopenharmony_ci output_case(sys.stdout, name, opts) 76