aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <maandree@operamail.com>2012-10-29 04:18:33 +0100
committerMattias Andrée <maandree@operamail.com>2012-10-29 04:18:33 +0100
commita76611cdf187039eba85f585d225a643789e13d2 (patch)
treebef25f8b1752202de65863c5b95adb6b5251c65f
parentbug fix (diff)
downloadauto-auto-complete-a76611cdf187039eba85f585d225a643789e13d2.tar.gz
auto-auto-complete-a76611cdf187039eba85f585d225a643789e13d2.tar.bz2
auto-auto-complete-a76611cdf187039eba85f585d225a643789e13d2.tar.xz
m + zsh
-rwxr-xr-xauto-auto-complete.py190
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