aboutsummaryrefslogtreecommitdiffstats
path: root/auto-auto-complete.py
diff options
context:
space:
mode:
authorMattias Andrée <maandree@operamail.com>2014-10-11 19:11:59 +0200
committerMattias Andrée <maandree@operamail.com>2014-10-11 19:11:59 +0200
commitae1e76535e6fb0fe9487161d78df993adff930b3 (patch)
treefb1ad7fdc2a46c9431195d0bbff9d6db8faea026 /auto-auto-complete.py
parentbump year (diff)
downloadauto-auto-complete-ae1e76535e6fb0fe9487161d78df993adff930b3.tar.gz
auto-auto-complete-ae1e76535e6fb0fe9487161d78df993adff930b3.tar.bz2
auto-auto-complete-ae1e76535e6fb0fe9487161d78df993adff930b3.tar.xz
prepare for adding info manual and auto-completion
Signed-off-by: Mattias Andrée <maandree@operamail.com>
Diffstat (limited to 'auto-auto-complete.py')
-rwxr-xr-xauto-auto-complete.py841
1 files changed, 0 insertions, 841 deletions
diff --git a/auto-auto-complete.py b/auto-auto-complete.py
deleted file mode 100755
index 35d8ab4..0000000
--- a/auto-auto-complete.py
+++ /dev/null
@@ -1,841 +0,0 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-'''
-auto-auto-complete – Autogenerate shell auto-completion scripts
-
-Copyright © 2012, 2013 Mattias Andrée (maandree@member.fsf.org)
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see <http://www.gnu.org/licenses/>.
-'''
-import sys
-
-
-'''
-Hack to enforce UTF-8 in output (in the future, if you see anypony not using utf-8 in
-programs by default, report them to Princess Celestia so she can banish them to the moon)
-
-@param text:str The text to print (empty string is default)
-@param end:str The appendix to the text to print (line breaking is default)
-'''
-def print(text = '', end = '\n'):
- sys.stdout.buffer.write((str(text) + end).encode('utf-8'))
-
-'''
-stderr equivalent to print()
-
-@param text:str The text to print (empty string is default)
-@param end:str The appendix to the text to print (line breaking is default)
-'''
-def printerr(text = '', end = '\n'):
- sys.stderr.buffer.write((str(text) + end).encode('utf-8'))
-
-
-'''
-Abort the program
-
-@param text:str Error message
-@return returncode:int The programs return code
-'''
-def abort(text, returncode = 1):
- printerr('\033[01;31m%s\033[00m' % text)
- sys.exit(returncode)
-
-
-
-
-'''
-Bracket tree parser
-'''
-class Parser:
- '''
- Parse a code and return a tree
-
- @param code:str The code to parse
- @return :list<↑|str> The root node in the tree
- '''
- @staticmethod
- def parse(code):
- stack = []
- stackptr = -1
-
- comment = False
- escape = False
- quote = None
- buf = None
-
- col = 0
- char = 0
- line = 1
-
- for charindex in range(0, len(code)):
- c = code[charindex]
- if comment:
- if c in '\n\r\f':
- comment = False
- elif escape:
- escape = False
- if c == 'a': buf += '\a'
- elif c == 'b': buf += chr(8)
- elif c == 'e': buf += '\033'
- elif c == 'f': buf += '\f'
- elif c == 'n': buf += '\n'
- elif c == 'r': buf += '\r'
- elif c == 't': buf += '\t'
- elif c == 'v': buf += chr(11)
- elif c == '0': buf += '\0'
- else:
- buf += c
- elif c == quote:
- quote = None
- elif (c in ';#') and (quote is None):
- if buf is not None:
- stack[stackptr].append(buf)
- buf = None
- comment = True
- elif (c == '(') and (quote is None):
- if buf is not None:
- stack[stackptr].append(buf)
- buf = None
- stackptr += 1
- if stackptr == len(stack):
- stack.append([])
- else:
- stack[stackptr] = []
- elif (c == ')') and (quote is None):
- if buf is not None:
- stack[stackptr].append(buf)
- buf = None
- if stackptr == 0:
- return stack[0]
- stackptr -= 1
- stack[stackptr].append(stack[stackptr + 1])
- elif (c in ' \t\n\r\f') and (quote is None):
- if buf is not None:
- stack[stackptr].append(buf)
- buf = None
- else:
- if buf is None:
- buf = ''
- if c == '\\':
- escape = True
- elif (c in '\'\"') and (quote is None):
- quote = c
- else:
- buf += c
-
- if c == '\t':
- col |= 7
- col += 1
- char += 1
- if c in '\n\r\f':
- line += 1
- col = 0
- char = 0
-
- abort('premature end of file')
-
-
- '''
- Simplifies a tree
-
- @param tree:list<↑|str> The tree
- '''
- @staticmethod
- def simplify(tree):
- global variables
- program = tree[0]
- stack = [tree]
- while len(stack) > 0:
- node = stack.pop()
- new = []
- edited = False
- for item in node:
- if isinstance(item, list):
- if item[0] == 'multiple':
- master = item[1]
- for slave in item[2:]:
- new.append([master] + slave)
- edited = True
- elif item[0] == 'case':
- for alt in item[1:]:
- if alt[0] == program:
- new.append(alt[1])
- break
- edited = True
- elif item[0] == 'value':
- variable = item[1]
- if variable in variables:
- for value in variables[variable]:
- new.append(value)
- else:
- if len(item) == 2:
- abort('Undefined variable: ' + variable)
- for value in item[2:]:
- new.append(value)
- edited = True
- else:
- new.append(item)
- else:
- new.append(item)
- if edited:
- node[:] = new
- for item in node:
- if isinstance(item, list):
- stack.append(item)
-
-
-
-'''
-Completion script generator for GNU Bash
-'''
-class GeneratorBASH:
- '''
- 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
-
-
- '''
- Returns the generated code
-
- @return :str The generated code
- '''
- def get(self):
- buf = '# bash completion for %s -*- shell-script -*-\n\n' % self.program
- buf += '_%s()\n{\n' % self.program
- buf += ' local cur prev words cword\n'
- buf += ' _init_completion -n = || return\n\n'
-
- 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])
-
- def makesuggestion(suggester):
- suggestion = '';
- for function in suggester:
- 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))
- return '"' + suggestion + '"'
-
- suggesters = self.__getSuggesters()
- suggestFunctions = {}
- for function in self.suggestion:
- suggestFunctions[function[0]] = function[1:]
-
- options = []
- for group in (self.unargumented, self.argumented, self.variadic):
- for item in group:
- if 'complete' in item:
- options += item['complete']
- buf += ' options="%s "' % (' '.join(options))
- if self.default is not None:
- defSuggest = self.default['suggest'][0]
- if defSuggest is not None:
- buf += '%s' % makesuggestion(suggestFunctions[defSuggest])
- buf += '\n'
- buf += ' COMPREPLY=( $( compgen -W "$options" -- "$cur" ) )\n\n'
-
- indenticals = {}
- for option in suggesters:
- suggester = suggestFunctions[suggesters[option]]
- _suggester = str(suggester)
- if _suggester not in indenticals:
- indenticals[_suggester] = (suggester, [option])
- else:
- indenticals[_suggester][1].append(option)
-
- index = 0
- for _suggester in indenticals:
- (suggester, options) = indenticals[_suggester]
- conds = []
- for option in options:
- conds.append('[ $prev = "%s" ]' % option)
- buf += ' %s %s; then\n' % ('if' if index == 0 else 'elif', ' || '.join(conds))
- suggestion = makesuggestion(suggester);
- if len(suggestion) > 0:
- buf += ' suggestions=%s\n' % suggestion
- buf += ' COMPREPLY=( $( compgen -W "$suggestions" -- "$cur" ) )\n'
- index += 1
-
- if index > 0:
- buf += ' fi\n'
-
- buf += '}\n\ncomplete -o default -F _%s %s\n\n' % (self.program, self.program)
- return buf
-
-
-
-'''
-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
- @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 = '# 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 + '"'
-
- if self.default is not None:
- item = self.default
- buf += 'complete --command %s' % self.program
- if 'desc' in self.default:
- buf += ' --description %s' % verb(' '.join(item['desc']))
- defFiles = self.default['files']
- defSuggest = self.default['suggest'][0]
- if defFiles is not None:
- if (len(defFiles) == 1) and ('-0' in defFiles):
- buf += ' --no-files'
- if defSuggest is not None:
- buf += ' --arguments %s' % suggestFunctions[defSuggest]
- buf += '\n'
-
- 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('--'):
- 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(longopt) == 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 (len(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][1:]
- if len( longopt) > 0: buf += ' --long-option %s' % longopt[0][2:]
- buf += '\n'
-
- return buf
-
-
-
-'''
-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 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
-
- 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\n_arguments "$_opts[@]"\n\n'
- return buf
-
-
-
-'''
-mane!
-
-@param shell:str Shell to generato completion for
-@param output:str Output file
-@param source:str Source file
-'''
-def main(shell, output, source):
- with open(source, 'rb') as file:
- source = file.read().decode('utf8', 'replace')
- source = Parser.parse(source)
- Parser.simplify(source)
-
- program = source[0]
- unargumented = []
- argumented = []
- variadic = []
- suggestion = []
- default = None
-
- for item in source[1:]:
- if item[0] == 'unargumented':
- unargumented.append(item[1:]);
- elif item[0] == 'argumented':
- argumented.append(item[1:]);
- elif item[0] == 'variadic':
- variadic.append(item[1:]);
- elif item[0] == 'suggestion':
- suggestion.append(item[1:]);
- elif item[0] == 'default':
- default = item[1:];
-
- for (group, not_allowed) in ((unargumented, ['arg', 'suggest', 'files']), (argumented, []), (variadic, [])):
- for index in range(0, len(group)):
- item = group[index]
- map = {}
- for elem in item:
- if elem[0] not in ('options', 'complete', 'arg', 'suggest', 'files', 'bind', 'desc'):
- abort('Unrecognised keyword: ' + elem[0])
- if elem[0] in not_allowed:
- abort('Out of context keyword: ' + elem[0])
- map[elem[0]] = elem[1:]
- group[index] = map
- if default is not None:
- map = {}
- for elem in default:
- if elem[0] not in ('arg', 'suggest', 'files', 'desc'):
- abort('Unrecognised keyword: ' + elem[0])
- if elem[0] in ('bind', 'options', 'complete'):
- abort('Out of context keyword: ' + elem[0])
- map[elem[0]] = elem[1:]
- default = map
-
- generator = 'Generator' + shell.upper()
- generator = globals()[generator]
- generator = generator(program, unargumented, argumented, variadic, suggestion, default)
- code = generator.get()
-
- with open(output, 'wb') as file:
- file.write(code.encode('utf-8'))
-
-
-
-'''
-mane!
-'''
-if __name__ == '__main__':
- if len(sys.argv) < 4:
- print("USAGE: auto-auto-complete SHELL --output OUTPUT_FILE --source SOURCE_FILE [VARIABLE=VALUE...]")
- exit(2)
-
- shell = None
- output = None
- source = None
- variables = {}
-
- option = None
- aliases = {'-o' : '--output',
- '-f' : '--source', '--file' : '--source',
- '-s' : '--source'}
-
- def useopt(option, arg):
- global source
- global output
- global variables
- old = None
- if option == '--output': old = output; output = arg
- elif option == '--source': old = source; source = arg
- elif not option.startswith('-'):
- if option not in variables:
- variables[option] = []
- variables[option].append(arg)
- else:
- abort('Unrecognised option: ' + option)
- if old is not None:
- abort('Duplicate option: ' + option)
-
- for arg in sys.argv[1:]:
- if option is not None:
- if option in aliases:
- option = aliases[option]
- useopt(option, arg)
- option = None
- elif (shell is None) and not arg.startswith('-'):
- shell = arg
- else:
- if '=' in arg:
- useopt(arg[:arg.index('=')], arg[arg.index('=') + 1:])
- else:
- option = arg
-
- if output is None: abort('Unused option: --output')
- if source is None: abort('Unused option: --source')
-
- main(shell= shell, output= output, source= source)
-