diff options
Diffstat (limited to '')
| -rwxr-xr-x | auto-auto-complete.py | 190 | 
1 files changed, 187 insertions, 3 deletions
| diff --git a/auto-auto-complete.py b/auto-auto-complete.py index 2f0d441..4722a0d 100755 --- a/auto-auto-complete.py +++ b/auto-auto-complete.py @@ -321,7 +321,7 @@ class GeneratorBASH:  ''' -Completion script generator for FISH +Completion script generator for fish  '''  class GeneratorFISH:      ''' @@ -485,11 +485,12 @@ class GeneratorFISH:                  longopt = []                  for opt in options:                      if opt.startswith('--'): -                        longopt.append(opt) +                        if ('complete' in item) and (opt in item['complete']): +                            longopt.append(opt)                      elif opt.startswith('-') and (len(opt) == 2):                          shortopt.append(opt)                  options = shortopt + longopt -                if len(options) == 0: +                if len(longopt) == 0:                      continue                  buf += 'complete --command %s' % self.program                  if 'desc' in item: @@ -508,6 +509,189 @@ class GeneratorFISH:  ''' +Completion script generator for zsh +''' +class GeneratorZSH: +    ''' +    Constructor +     +    @param  program:str                              The command to generate completion for +    @param  unargumented:list<dict<str, list<str>>>  Specification of unargumented options +    @param  argumented:list<dict<str, list<str>>>    Specification of argumented options +    @param  variadic:list<dict<str, list<str>>>      Specification of variadic options +    @param  suggestion:list<list<↑|str>>             Specification of argument suggestions +    @param  default:dict<str, list<str>>?            Specification for optionless arguments +    ''' +    def __init__(self, program, unargumented, argumented, variadic, suggestion, default): +        self.program      = program +        self.unargumented = unargumented +        self.argumented   = argumented +        self.variadic     = variadic +        self.suggestion   = suggestion +        self.default      = default +     +     +    ''' +    Gets the argument suggesters for each option +     +    @return  :dist<str, str>  Map from option to suggester +    ''' +    def __getSuggesters(self): +        suggesters = {} +         +        for group in (self.unargumented, self.argumented, self.variadic): +            for item in group: +                if 'suggest' in item: +                    suggester = item['suggest'] +                    for option in item['options']: +                        suggesters[option] = suggester[0] +         +        for group in (self.unargumented, self.argumented, self.variadic): +            for item in group: +                if ('suggest' not in item) and ('bind' in item): +                    bind = item['bind'][0] +                    if bind in suggesters: +                        suggester = suggesters[bind] +                        for option in item['options']: +                            suggesters[option] = suggester +         +        return suggesters +     +     +    ''' +    Gets the file pattern for each option +     +    @return  :dist<str, list<str>>  Map from option to file pattern +    ''' +    def __getFiles(self): +        files = {} +         +        for group in (self.unargumented, self.argumented, self.variadic): +            for item in group: +                if 'files' in item: +                    _files = item['files'] +                    for option in item['options']: +                        files[option] = _files +         +        for group in (self.unargumented, self.argumented, self.variadic): +            for item in group: +                if ('files' not in item) and ('bind' in item): +                    bind = item['bind'][0] +                    if bind in files: +                        _files = files[bind] +                        for option in item['options']: +                            files[option] = _files +         +        return files +     +     +    ''' +    Returns the generated code +     +    @return  :str  The generated code +    ''' +    def get(self): +        buf = '# zsh completion for %s         -*- shell-script -*-\n\n' % self.program +         +        files = self.__getFiles() +         +        suggesters = self.__getSuggesters() +        suggestFunctions = {} +        for function in self.suggestion: +            suggestFunctions[function[0]] = function[1:] +         +        def verb(text): +            temp = text +            for char in 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-+=/@:\'': +                temp = temp.replace(char, '') +            if len(temp) == 0: +                return text +            return '\'' + text.replace('\'', '\'\\\'\'') + '\'' +         +        def makeexec(functionType, function): +            if functionType in ('exec', 'pipe', 'fullpipe', 'cat', 'and', 'or'): +                elems = [(' %s ' % makeexec(item[0], item[1:]) if isinstance(item, list) else verb(item)) for item in function] +                if functionType == 'exec': +                    return ' $( %s ) ' % (' '.join(elems)) +                if functionType == 'pipe': +                    return ' ( %s ) ' % (' | '.join(elems)) +                if functionType == 'fullpipe': +                    return ' ( %s ) ' % (' |% '.join(elems)) +                if functionType == 'cat': +                    return ' ( %s ) ' % (' ; '.join(elems)) +                if functionType == 'and': +                    return ' ( %s ) ' % (' && '.join(elems)) +                if functionType == 'or': +                    return ' ( %s ) ' % (' || '.join(elems)) +            if functionType in ('params', 'verbatim'): +                return ' '.join([verb(item) for item in function]) +            return ' '.join([verb(functionType)] + [verb(item) for item in function]) +         +        index = 0 +        for name in suggestFunctions: +            suggestion = ''; +            for function in suggestFunctions[name]: +                functionType = function[0] +                function = function[1:] +                if functionType == 'verbatim': +                    suggestion += '(%s)' % (' '.join([verb(item) for item in function])) +                elif functionType == 'ls': +                    filter = '' +                    if len(function) > 1: +                        filter = ' | grep -v \\/%s\\$ | grep %s\\$' % (function[1], function[1]) +                    suggestion += '$(ls -1 --color=no %s%s)' % (function[0], filter) +                elif functionType == 'exec': +                    elem = makeexec(functionType, function) +                    elem = elem[4:] +                    elem = elem[:-3] +                    suggestion += elem +                elif functionType in ('pipe', 'fullpipe', 'cat', 'and', 'or'): +                    suggestion += ('%s' if functionType == 'exec' else '$(%s)') % makeexec(functionType, function) +                elif functionType == 'calc': +                    expression = [] +                    for item in function: +                        if isinstance(item, list): +                            expression.append(('%s' if item[0] == 'exec' else '$(%s)') % makeexec(item[0], item[1:])) +                        else: +                            expression.append(verb(item)) +                    suggestion += '$(( %s ))' % (' '.join(expression)) +            if len(suggestion) > 0: +                suggestFunctions[name] = '"' + suggestion + '"' +         +        buf += '_opts=(\n' +         +        for group in (self.unargumented, self.argumented, self.variadic): +            for item in group: +                options = item['options'] +                shortopt = [] +                longopt = [] +                for opt in options: +                    if len(opt) > 2: +                        if ('complete' in item) and (opt in item['complete']): +                            longopt.append(opt) +                    elif len(opt) == 2: +                        shortopt.append(opt) +                options = shortopt + longopt +                if len(longopt) == 0: +                    continue +                buf += '    \'(%s)\'{%s}' % (' '.join(options), ','.join(options)) +                if 'desc' in item: +                    buf += '"["%s"]"' % verb(' '.join(item['desc'])) +                if 'arg' in item: +                    buf += ':%s' % verb(' '.join(item['arg'])) +                elif options[0] in suggesters: +                    buf += ': ' +                if options[0] in suggesters: +                    suggestion = suggestFunctions[suggesters[options[0]]] +                    buf += ':%s' % suggestion +                buf += '\n' +         +        buf += '    )\n_arguments "$_opts[@]"\n\n' +        return buf + + + +'''  mane!  @param  shell:str   Shell to generato completion for | 
