diff options
author | Terry Howe <terrylhowe@gmail.com> | 2013-10-30 17:25:59 -0600 |
---|---|---|
committer | Terry Howe <terrylhowe@gmail.com> | 2013-10-30 17:25:59 -0600 |
commit | 5d33c97404e5661bca62b1e9907740ee83cec3c6 (patch) | |
tree | 18b4566669b54d765c189143558093ad3c32a3c9 /cliff/complete.py | |
parent | 5be07a22eb8197d805af7954316f8c29e3a66c3f (diff) | |
download | cliff-5d33c97404e5661bca62b1e9907740ee83cec3c6.tar.gz |
various python code optimizations; shuffle I/O to shell classes
Diffstat (limited to 'cliff/complete.py')
-rw-r--r-- | cliff/complete.py | 163 |
1 files changed, 78 insertions, 85 deletions
diff --git a/cliff/complete.py b/cliff/complete.py index 24cb7e4..c31c659 100644 --- a/cliff/complete.py +++ b/cliff/complete.py @@ -15,42 +15,26 @@ class CompleteDictionary: self._dictionary = {} def add_command(self, command, actions): - optstr = "" + optstr = ' '.join(opt for action in actions + for opt in action.option_strings) dicto = self._dictionary - for action in actions: - for opt in action.option_strings: - if optstr: - optstr += " " + opt - else: - optstr += opt last = None lastsubcmd = None - for subcmd in command: - if subcmd not in dicto: - dicto[subcmd] = {} - last = dicto - lastsubcmd = subcmd - dicto = dicto[subcmd] - last[lastsubcmd] = optstr + for subcmd in command[:-1]: + dicto = dicto.setdefault(subcmd, {}) + dicto[command[-1]] = optstr def get_commands(self): - cmdo = "" - keys = sorted(self._dictionary.keys()) - for cmd in keys: - if cmdo == "": - cmdo += cmd - else: - cmdo += " " + cmd - return cmdo + return ' '.join(k for k in sorted(self._dictionary.keys())) def _get_data_recurse(self, dictionary, path): ray = [] keys = sorted(dictionary.keys()) for cmd in keys: if path == "": - name = str(cmd) + name = cmd else: - name = path + "_" + str(cmd) + name = path + "_" + cmd value = dictionary[cmd] if isinstance(value, str): ray.append((name, value)) @@ -64,11 +48,25 @@ class CompleteDictionary: return sorted(self._get_data_recurse(self._dictionary, "")) -class CompleteNoCode: +class CompleteShellBase(object): + """ base class for bash completion generation + """ + def __init__(self, name, output): + self.name = str(name) + self.output = output + + def write(self, cmdo, data): + self.output.write(self.get_header()) + self.output.write(" cmds='{0}'\n".format(cmdo)) + for datum in data: + self.output.write(' cmds_{0}=\'{1}\'\n'.format(*datum)) + self.output.write(self.get_trailer()) + +class CompleteNoCode(CompleteShellBase): """completion with no code """ - def __init__(self, name): - self.name = name + def __init__(self, name, output): + super(CompleteNoCode, self).__init__(name, output) def get_header(self): return '' @@ -77,60 +75,62 @@ class CompleteNoCode: return '' -class CompleteBash: +class CompleteBash(CompleteShellBase): """completion for bash """ - def __init__(self, name): - self.name = str(name) + def __init__(self, name, output): + super(CompleteBash, self).__init__(name, output) def get_header(self): - return ('_' + self.name + '()\n\ -{\n\ - local cur prev words\n\ - COMPREPLY=()\n\ - _get_comp_words_by_ref -n : cur prev words\n\ -\n\ - # Command data:\n') + return ('_' + self.name + """() +{ + local cur prev words + COMPREPLY=() + _get_comp_words_by_ref -n : cur prev words + + # Command data: +""") def get_trailer(self): - return ('\ -\n\ - cmd=""\n\ - words[0]=""\n\ - completed="${cmds}" \n\ - for var in "${words[@]:1}"\n\ - do\n\ - if [[ ${var} == -* ]] ; then\n\ - break\n\ - fi\n\ - if [ -z "${cmd}" ] ; then\n\ - proposed="${var}"\n\ - else\n\ - proposed="${cmd}_${var}"\n\ - fi\n\ - local i="cmds_${proposed}"\n\ - local comp="${!i}"\n\ - if [ -z "${comp}" ] ; then\n\ - break\n\ - fi\n\ - if [[ ${comp} == -* ]] ; then\n\ - if [[ ${cur} != -* ]] ; then\n\ - completed=""\n\ - break\n\ - fi\n\ - fi\n\ - cmd="${proposed}"\n\ - completed="${comp}"\n\ - done\n\ -\n\ - if [ -z "${completed}" ] ; then\n\ - COMPREPLY=( $( compgen -f -- "$cur" ) $( compgen -d -- "$cur" ) )\n\ - else\n\ - COMPREPLY=( $(compgen -W "${completed}" -- ${cur}) )\n\ - fi\n\ - return 0\n\ -}\n\ -complete -F _' + self.name + ' ' + self.name + '\n') + return ( +""" + + cmd="" + words[0]="" + completed="${cmds}" + for var in "${words[@]:1}" + do + if [[ ${var} == -* ]] ; then + break + fi + if [ -z "${cmd}" ] ; then + proposed="${var}" + else + proposed="${cmd}_${var}" + fi + local i="cmds_${proposed}" + local comp="${!i}" + if [ -z "${comp}" ] ; then + break + fi + if [[ ${comp} == -* ]] ; then + if [[ ${cur} != -* ]] ; then + completed="" + break + fi + fi + cmd="${proposed}" + completed="${comp}" + done + + if [ -z "${completed}" ] ; then + COMPREPLY=( $( compgen -f -- "$cur" ) $( compgen -d -- "$cur" ) ) + else + COMPREPLY=( $(compgen -W "${completed}" -- ${cur}) ) + fi + return 0 +} +complete -F _""" + self.name + ' ' + self.name + '\n') class CompleteCommand(command.Command): @@ -175,22 +175,15 @@ class CompleteCommand(command.Command): else: name = self.app.NAME if parsed_args.shell == "none": - shell = CompleteNoCode(name) + shell = CompleteNoCode(name, self.app.stdout) else: - shell = CompleteBash(name) - - self.app.stdout.write(shell.get_header()) + shell = CompleteBash(name, self.app.stdout) dicto = CompleteDictionary() for cmd in self.app.command_manager: command = cmd[0].split() dicto.add_command(command, self.get_actions(command)) - cmdo = dicto.get_commands() - self.app.stdout.write(" cmds='{0}'\n".format(cmdo)) - for datum in dicto.get_data(): - self.app.stdout.write(' cmds_{0}=\'{1}\'\n'.format(*datum)) - - self.app.stdout.write(shell.get_trailer()) + shell.write(dicto.get_commands(), dicto.get_data()) return 0 |