aboutsummaryrefslogtreecommitdiffstats
path: root/auto-auto-complete.py
diff options
context:
space:
mode:
Diffstat (limited to 'auto-auto-complete.py')
-rwxr-xr-xauto-auto-complete.py178
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