diff options
Diffstat (limited to '')
-rwxr-xr-x | auto-auto-complete.py | 178 |
1 files changed, 175 insertions, 3 deletions
diff --git a/auto-auto-complete.py b/auto-auto-complete.py index e4cfadc..db4576f 100755 --- a/auto-auto-complete.py +++ b/auto-auto-complete.py @@ -184,7 +184,7 @@ class GeneratorBASH: ''' Gets the argument suggesters for each option - @param :dist<str, str> Map from option to suggester + @return :dist<str, str> Map from option to suggester ''' def __getSuggesters(self): suggesters = {} @@ -227,7 +227,7 @@ class GeneratorBASH: buf += ' options="%s"\n' % (' '.join(options)) buf += ' COMPREPLY=( $( compgen -W "$options" -- "$cur" ) )\n\n' - suggesters = self.__getSuggesters(); + suggesters = self.__getSuggesters() suggestFunctions = {} for function in self.suggestion: suggestFunctions[function[0]] = function[1:] @@ -297,7 +297,7 @@ class GeneratorBASH: expression.append(verb(item)) suggestion += '" $(( %s ))"' % (' '.join(expression)) if len(suggestion) > 0: - buf += ' suggestions=%s\n' % str(suggestion) + buf += ' suggestions=%s\n' % suggestion buf += ' COMPREPLY=( $( compgen -W "$suggestions" -- "$cur" ) )\n' index += 1 @@ -310,6 +310,178 @@ class GeneratorBASH: ''' +Completion script generator for FISH +''' +class GeneratorFISH: + ''' + 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 + ''' + def __init__(self, program, unargumented, argumented, variadic, suggestion): + self.program = program + self.unargumented = unargumented + self.argumented = argumented + self.variadic = variadic + self.suggestion = suggestion + + + ''' + 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 = '# fish 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 in ('exec', '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 + + for group in (self.unargumented, self.argumented, self.variadic): + for item in group: + options = item['options'] + shortopt = [] + longopt = [] + for opt in options: + if opt.startswith('--'): + longopt.append(opt) + elif opt.startswith('-') and (len(opt) == 2): + shortopt.append(opt) + options = shortopt + longopt + if len(options) == 0: + continue + buf += 'complete --command %s' % self.program + if 'desc' in item: + buf += ' --description %s' % verb(' '.join(item['desc'])) + if options[0] in files: + if (files[options[0]] == 1) and ('-0' in files[options[0]][0]): + buf += ' --no-files' + if options[0] in suggesters: + buf += ' --arguments %s' % suggestFunctions[suggesters[options[0]]] + if len(shortopt) > 0: buf += ' --short-option %s' % shortopt[0] + if len( longopt) > 0: buf += ' --long-option %s' % longopt[0] + buf += '\n' + + return buf + + + +''' mane! @param shell:str Shell to generato completion for |