mirror of
https://github.com/erkin/ponysay.git
synced 2024-11-22 12:27:59 +01:00
parent
2095244c65
commit
5cd37c81b7
1 changed files with 221 additions and 133 deletions
|
@ -5,16 +5,13 @@
|
||||||
###############################################################################################
|
###############################################################################################
|
||||||
## Shell auto-completion script generator https://www.github.com/maandree/auto-auto-complete ##
|
## Shell auto-completion script generator https://www.github.com/maandree/auto-auto-complete ##
|
||||||
## Used by build system to make completions for all supported shells. ##
|
## Used by build system to make completions for all supported shells. ##
|
||||||
## ##
|
|
||||||
## auto-auto-complete is experimental, therefore, before updating the version of this ##
|
|
||||||
## make sure that is still work for all shells. ##
|
|
||||||
###############################################################################################
|
###############################################################################################
|
||||||
|
|
||||||
|
|
||||||
'''
|
'''
|
||||||
auto-auto-complete – Autogenerate shell auto-completion scripts
|
auto-auto-complete – Autogenerate shell auto-completion scripts
|
||||||
|
|
||||||
Copyright © 2012 Mattias Andrée (maandree@kth.se)
|
Copyright © 2012, 2013, 2014, 2015 Mattias Andrée (maandree@member.fsf.org)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -32,40 +29,51 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
import sys
|
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'):
|
def print(text = '', end = '\n'):
|
||||||
|
'''
|
||||||
|
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)
|
||||||
|
'''
|
||||||
sys.stdout.buffer.write((str(text) + end).encode('utf-8'))
|
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'):
|
def printerr(text = '', end = '\n'):
|
||||||
|
'''
|
||||||
|
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)
|
||||||
|
'''
|
||||||
sys.stderr.buffer.write((str(text) + end).encode('utf-8'))
|
sys.stderr.buffer.write((str(text) + end).encode('utf-8'))
|
||||||
|
|
||||||
|
|
||||||
|
def abort(text, returncode = 1):
|
||||||
|
'''
|
||||||
|
Abort the program
|
||||||
|
|
||||||
|
@param text:str Error message
|
||||||
|
@return returncode:int The programs return code
|
||||||
|
'''
|
||||||
|
printerr('\033[01;31m%s\033[00m' % text)
|
||||||
|
sys.exit(returncode)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
'''
|
|
||||||
Bracket tree parser
|
|
||||||
'''
|
|
||||||
class Parser:
|
class Parser:
|
||||||
'''
|
'''
|
||||||
Parse a code and return a tree
|
Bracket tree parser
|
||||||
|
|
||||||
@param code:str The code to parse
|
|
||||||
@return :list<↑|str> The root node in the tree
|
|
||||||
'''
|
'''
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def parse(code):
|
def parse(code):
|
||||||
|
'''
|
||||||
|
Parse a code and return a tree
|
||||||
|
|
||||||
|
@param code:str The code to parse
|
||||||
|
@return :list<↑|str> The root node in the tree
|
||||||
|
'''
|
||||||
stack = []
|
stack = []
|
||||||
stackptr = -1
|
stackptr = -1
|
||||||
|
|
||||||
|
@ -74,6 +82,10 @@ class Parser:
|
||||||
quote = None
|
quote = None
|
||||||
buf = None
|
buf = None
|
||||||
|
|
||||||
|
col = 0
|
||||||
|
char = 0
|
||||||
|
line = 1
|
||||||
|
|
||||||
for charindex in range(0, len(code)):
|
for charindex in range(0, len(code)):
|
||||||
c = code[charindex]
|
c = code[charindex]
|
||||||
if comment:
|
if comment:
|
||||||
|
@ -130,16 +142,26 @@ class Parser:
|
||||||
else:
|
else:
|
||||||
buf += c
|
buf += c
|
||||||
|
|
||||||
raise Exception('premature end of file')
|
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
|
@staticmethod
|
||||||
def simplify(tree):
|
def simplify(tree):
|
||||||
|
'''
|
||||||
|
Simplifies a tree
|
||||||
|
|
||||||
|
@param tree:list<↑|str> The tree
|
||||||
|
'''
|
||||||
|
global variables
|
||||||
program = tree[0]
|
program = tree[0]
|
||||||
stack = [tree]
|
stack = [tree]
|
||||||
while len(stack) > 0:
|
while len(stack) > 0:
|
||||||
|
@ -159,6 +181,17 @@ class Parser:
|
||||||
new.append(alt[1])
|
new.append(alt[1])
|
||||||
break
|
break
|
||||||
edited = True
|
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:
|
else:
|
||||||
new.append(item)
|
new.append(item)
|
||||||
else:
|
else:
|
||||||
|
@ -171,21 +204,21 @@ class Parser:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
'''
|
|
||||||
Completion script generator for GNU Bash
|
|
||||||
'''
|
|
||||||
class GeneratorBASH:
|
class GeneratorBASH:
|
||||||
'''
|
'''
|
||||||
Constructor
|
Completion script generator for GNU Bash
|
||||||
|
|
||||||
@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):
|
def __init__(self, program, unargumented, argumented, variadic, suggestion, default):
|
||||||
|
'''
|
||||||
|
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
|
||||||
|
'''
|
||||||
self.program = program
|
self.program = program
|
||||||
self.unargumented = unargumented
|
self.unargumented = unargumented
|
||||||
self.argumented = argumented
|
self.argumented = argumented
|
||||||
|
@ -194,12 +227,12 @@ class GeneratorBASH:
|
||||||
self.default = default
|
self.default = default
|
||||||
|
|
||||||
|
|
||||||
'''
|
|
||||||
Gets the argument suggesters for each option
|
|
||||||
|
|
||||||
@return :dist<str, str> Map from option to suggester
|
|
||||||
'''
|
|
||||||
def __getSuggesters(self):
|
def __getSuggesters(self):
|
||||||
|
'''
|
||||||
|
Gets the argument suggesters for each option
|
||||||
|
|
||||||
|
@return :dist<str, str> Map from option to suggester
|
||||||
|
'''
|
||||||
suggesters = {}
|
suggesters = {}
|
||||||
|
|
||||||
for group in (self.unargumented, self.argumented, self.variadic):
|
for group in (self.unargumented, self.argumented, self.variadic):
|
||||||
|
@ -221,12 +254,12 @@ class GeneratorBASH:
|
||||||
return suggesters
|
return suggesters
|
||||||
|
|
||||||
|
|
||||||
'''
|
|
||||||
Returns the generated code
|
|
||||||
|
|
||||||
@return :str The generated code
|
|
||||||
'''
|
|
||||||
def get(self):
|
def get(self):
|
||||||
|
'''
|
||||||
|
Returns the generated code
|
||||||
|
|
||||||
|
@return :str The generated code
|
||||||
|
'''
|
||||||
buf = '# bash completion for %s -*- shell-script -*-\n\n' % self.program
|
buf = '# bash completion for %s -*- shell-script -*-\n\n' % self.program
|
||||||
buf += '_%s()\n{\n' % self.program
|
buf += '_%s()\n{\n' % self.program
|
||||||
buf += ' local cur prev words cword\n'
|
buf += ' local cur prev words cword\n'
|
||||||
|
@ -248,7 +281,7 @@ class GeneratorBASH:
|
||||||
if functionType == 'pipe':
|
if functionType == 'pipe':
|
||||||
return ' ( %s ) ' % (' | '.join(elems))
|
return ' ( %s ) ' % (' | '.join(elems))
|
||||||
if functionType == 'fullpipe':
|
if functionType == 'fullpipe':
|
||||||
return ' ( %s ) ' % (' |% '.join(elems))
|
return ' ( %s ) ' % (' |& '.join(elems))
|
||||||
if functionType == 'cat':
|
if functionType == 'cat':
|
||||||
return ' ( %s ) ' % (' ; '.join(elems))
|
return ' ( %s ) ' % (' ; '.join(elems))
|
||||||
if functionType == 'and':
|
if functionType == 'and':
|
||||||
|
@ -330,22 +363,27 @@ class GeneratorBASH:
|
||||||
return buf
|
return buf
|
||||||
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def where(command):
|
||||||
|
return '/share/bash-completion/completions/%s' % command
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
'''
|
|
||||||
Completion script generator for fish
|
|
||||||
'''
|
|
||||||
class GeneratorFISH:
|
class GeneratorFISH:
|
||||||
'''
|
'''
|
||||||
Constructor
|
Completion script generator for fish
|
||||||
|
|
||||||
@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):
|
def __init__(self, program, unargumented, argumented, variadic, suggestion, default):
|
||||||
|
'''
|
||||||
|
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
|
||||||
|
'''
|
||||||
self.program = program
|
self.program = program
|
||||||
self.unargumented = unargumented
|
self.unargumented = unargumented
|
||||||
self.argumented = argumented
|
self.argumented = argumented
|
||||||
|
@ -354,12 +392,12 @@ class GeneratorFISH:
|
||||||
self.default = default
|
self.default = default
|
||||||
|
|
||||||
|
|
||||||
'''
|
|
||||||
Gets the argument suggesters for each option
|
|
||||||
|
|
||||||
@return :dist<str, str> Map from option to suggester
|
|
||||||
'''
|
|
||||||
def __getSuggesters(self):
|
def __getSuggesters(self):
|
||||||
|
'''
|
||||||
|
Gets the argument suggesters for each option
|
||||||
|
|
||||||
|
@return :dist<str, str> Map from option to suggester
|
||||||
|
'''
|
||||||
suggesters = {}
|
suggesters = {}
|
||||||
|
|
||||||
for group in (self.unargumented, self.argumented, self.variadic):
|
for group in (self.unargumented, self.argumented, self.variadic):
|
||||||
|
@ -381,12 +419,12 @@ class GeneratorFISH:
|
||||||
return suggesters
|
return suggesters
|
||||||
|
|
||||||
|
|
||||||
'''
|
|
||||||
Gets the file pattern for each option
|
|
||||||
|
|
||||||
@return :dist<str, list<str>> Map from option to file pattern
|
|
||||||
'''
|
|
||||||
def __getFiles(self):
|
def __getFiles(self):
|
||||||
|
'''
|
||||||
|
Gets the file pattern for each option
|
||||||
|
|
||||||
|
@return :dist<str, list<str>> Map from option to file pattern
|
||||||
|
'''
|
||||||
files = {}
|
files = {}
|
||||||
|
|
||||||
for group in (self.unargumented, self.argumented, self.variadic):
|
for group in (self.unargumented, self.argumented, self.variadic):
|
||||||
|
@ -408,12 +446,12 @@ class GeneratorFISH:
|
||||||
return files
|
return files
|
||||||
|
|
||||||
|
|
||||||
'''
|
|
||||||
Returns the generated code
|
|
||||||
|
|
||||||
@return :str The generated code
|
|
||||||
'''
|
|
||||||
def get(self):
|
def get(self):
|
||||||
|
'''
|
||||||
|
Returns the generated code
|
||||||
|
|
||||||
|
@return :str The generated code
|
||||||
|
'''
|
||||||
buf = '# fish completion for %s -*- shell-script -*-\n\n' % self.program
|
buf = '# fish completion for %s -*- shell-script -*-\n\n' % self.program
|
||||||
|
|
||||||
files = self.__getFiles()
|
files = self.__getFiles()
|
||||||
|
@ -439,7 +477,7 @@ class GeneratorFISH:
|
||||||
if functionType == 'pipe':
|
if functionType == 'pipe':
|
||||||
return ' ( %s ) ' % (' | '.join(elems))
|
return ' ( %s ) ' % (' | '.join(elems))
|
||||||
if functionType == 'fullpipe':
|
if functionType == 'fullpipe':
|
||||||
return ' ( %s ) ' % (' |% '.join(elems))
|
return ' ( %s ) ' % (' |& '.join(elems))
|
||||||
if functionType == 'cat':
|
if functionType == 'cat':
|
||||||
return ' ( %s ) ' % (' ; '.join(elems))
|
return ' ( %s ) ' % (' ; '.join(elems))
|
||||||
if functionType == 'and':
|
if functionType == 'and':
|
||||||
|
@ -519,22 +557,27 @@ class GeneratorFISH:
|
||||||
return buf
|
return buf
|
||||||
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def where(command):
|
||||||
|
return '/share/fish/completions/%s.fish' % command
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
'''
|
|
||||||
Completion script generator for zsh
|
|
||||||
'''
|
|
||||||
class GeneratorZSH:
|
class GeneratorZSH:
|
||||||
'''
|
'''
|
||||||
Constructor
|
Completion script generator for zsh
|
||||||
|
|
||||||
@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):
|
def __init__(self, program, unargumented, argumented, variadic, suggestion, default):
|
||||||
|
'''
|
||||||
|
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
|
||||||
|
'''
|
||||||
self.program = program
|
self.program = program
|
||||||
self.unargumented = unargumented
|
self.unargumented = unargumented
|
||||||
self.argumented = argumented
|
self.argumented = argumented
|
||||||
|
@ -543,12 +586,12 @@ class GeneratorZSH:
|
||||||
self.default = default
|
self.default = default
|
||||||
|
|
||||||
|
|
||||||
'''
|
|
||||||
Gets the argument suggesters for each option
|
|
||||||
|
|
||||||
@return :dist<str, str> Map from option to suggester
|
|
||||||
'''
|
|
||||||
def __getSuggesters(self):
|
def __getSuggesters(self):
|
||||||
|
'''
|
||||||
|
Gets the argument suggesters for each option
|
||||||
|
|
||||||
|
@return :dist<str, str> Map from option to suggester
|
||||||
|
'''
|
||||||
suggesters = {}
|
suggesters = {}
|
||||||
|
|
||||||
for group in (self.unargumented, self.argumented, self.variadic):
|
for group in (self.unargumented, self.argumented, self.variadic):
|
||||||
|
@ -570,12 +613,12 @@ class GeneratorZSH:
|
||||||
return suggesters
|
return suggesters
|
||||||
|
|
||||||
|
|
||||||
'''
|
|
||||||
Gets the file pattern for each option
|
|
||||||
|
|
||||||
@return :dist<str, list<str>> Map from option to file pattern
|
|
||||||
'''
|
|
||||||
def __getFiles(self):
|
def __getFiles(self):
|
||||||
|
'''
|
||||||
|
Gets the file pattern for each option
|
||||||
|
|
||||||
|
@return :dist<str, list<str>> Map from option to file pattern
|
||||||
|
'''
|
||||||
files = {}
|
files = {}
|
||||||
|
|
||||||
for group in (self.unargumented, self.argumented, self.variadic):
|
for group in (self.unargumented, self.argumented, self.variadic):
|
||||||
|
@ -597,13 +640,13 @@ class GeneratorZSH:
|
||||||
return files
|
return files
|
||||||
|
|
||||||
|
|
||||||
'''
|
|
||||||
Returns the generated code
|
|
||||||
|
|
||||||
@return :str The generated code
|
|
||||||
'''
|
|
||||||
def get(self):
|
def get(self):
|
||||||
buf = '# zsh completion for %s -*- shell-script -*-\n\n' % self.program
|
'''
|
||||||
|
Returns the generated code
|
||||||
|
|
||||||
|
@return :str The generated code
|
||||||
|
'''
|
||||||
|
buf = '#compdef %s\n\n' % self.program
|
||||||
|
|
||||||
files = self.__getFiles()
|
files = self.__getFiles()
|
||||||
|
|
||||||
|
@ -628,7 +671,7 @@ class GeneratorZSH:
|
||||||
if functionType == 'pipe':
|
if functionType == 'pipe':
|
||||||
return ' ( %s ) ' % (' | '.join(elems))
|
return ' ( %s ) ' % (' | '.join(elems))
|
||||||
if functionType == 'fullpipe':
|
if functionType == 'fullpipe':
|
||||||
return ' ( %s ) ' % (' |% '.join(elems))
|
return ' ( %s ) ' % (' |& '.join(elems))
|
||||||
if functionType == 'cat':
|
if functionType == 'cat':
|
||||||
return ' ( %s ) ' % (' ; '.join(elems))
|
return ' ( %s ) ' % (' ; '.join(elems))
|
||||||
if functionType == 'and':
|
if functionType == 'and':
|
||||||
|
@ -697,15 +740,20 @@ class GeneratorZSH:
|
||||||
return buf
|
return buf
|
||||||
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def where(command):
|
||||||
|
return '/share/zsh/site-functions/_%s' % command
|
||||||
|
|
||||||
|
|
||||||
'''
|
|
||||||
mane!
|
|
||||||
|
|
||||||
@param shell:str Shell to generato completion for
|
|
||||||
@param output:str Output file
|
|
||||||
@param source:str Source file
|
|
||||||
'''
|
|
||||||
def main(shell, output, source):
|
def main(shell, output, source):
|
||||||
|
'''
|
||||||
|
mane!
|
||||||
|
|
||||||
|
@param shell:str Shell for which to generate completion
|
||||||
|
@param output:str Output file
|
||||||
|
@param source:str Source file
|
||||||
|
'''
|
||||||
with open(source, 'rb') as file:
|
with open(source, 'rb') as file:
|
||||||
source = file.read().decode('utf8', 'replace')
|
source = file.read().decode('utf8', 'replace')
|
||||||
source = Parser.parse(source)
|
source = Parser.parse(source)
|
||||||
|
@ -730,20 +778,30 @@ def main(shell, output, source):
|
||||||
elif item[0] == 'default':
|
elif item[0] == 'default':
|
||||||
default = item[1:];
|
default = item[1:];
|
||||||
|
|
||||||
for group in (unargumented, argumented, variadic):
|
for (group, not_allowed) in ((unargumented, ['arg', 'suggest', 'files']), (argumented, []), (variadic, [])):
|
||||||
for index in range(0, len(group)):
|
for index in range(0, len(group)):
|
||||||
item = group[index]
|
item = group[index]
|
||||||
map = {}
|
map = {}
|
||||||
for elem in item:
|
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:]
|
map[elem[0]] = elem[1:]
|
||||||
group[index] = map
|
group[index] = map
|
||||||
if default is not None:
|
if default is not None:
|
||||||
map = {}
|
map = {}
|
||||||
for elem in default:
|
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:]
|
map[elem[0]] = elem[1:]
|
||||||
default = map
|
default = map
|
||||||
|
|
||||||
generator = 'Generator' + shell.upper()
|
generator = 'Generator' + shell.upper()
|
||||||
|
if generator not in globals():
|
||||||
|
abort('%s is not a supported shell' % shell)
|
||||||
generator = globals()[generator]
|
generator = globals()[generator]
|
||||||
generator = generator(program, unargumented, argumented, variadic, suggestion, default)
|
generator = generator(program, unargumented, argumented, variadic, suggestion, default)
|
||||||
code = generator.get()
|
code = generator.get()
|
||||||
|
@ -753,48 +811,78 @@ def main(shell, output, source):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
'''
|
def where_main(shell, command):
|
||||||
mane!
|
'''
|
||||||
'''
|
--where mane!
|
||||||
if __name__ == '__main__':
|
|
||||||
if len(sys.argv) != 6:
|
|
||||||
print("USAGE: auto-auto-complete SHELL --output OUTPUT_FILE --source SOURCE_FILE")
|
|
||||||
exit(1)
|
|
||||||
|
|
||||||
shell = sys.argv[1]
|
@param shell:str Shell for which the completion should be installed
|
||||||
|
@param command:str The commmad name
|
||||||
|
'''
|
||||||
|
generator = 'Generator' + shell.upper()
|
||||||
|
if generator not in globals():
|
||||||
|
abort('%s is not a supported shell' % shell)
|
||||||
|
generator = globals()[generator]
|
||||||
|
print(generator.where(command))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# supermane!
|
||||||
|
if __name__ == '__main__':
|
||||||
|
if (len(sys.argv) == 1) or ((len(sys.argv) == 2) and (sys.argv[1] in ('-h', '--help'))):
|
||||||
|
print("USAGE: auto-auto-complete SHELL --output OUTPUT_FILE --source SOURCE_FILE [VARIABLE=VALUE...]")
|
||||||
|
print(" or: auto-auto-complete SHELL --where COMMAND")
|
||||||
|
exit(2)
|
||||||
|
|
||||||
|
shell = None
|
||||||
output = None
|
output = None
|
||||||
source = None
|
source = None
|
||||||
|
where = None
|
||||||
|
variables = {}
|
||||||
|
|
||||||
option = None
|
option = None
|
||||||
aliases = {'-o' : '--output',
|
aliases = {'-o' : '--output',
|
||||||
'-f' : '--source', '--file' : '--source',
|
'-f' : '--source', '--file' : '--source',
|
||||||
'-s' : '--source'}
|
'-s' : '--source',
|
||||||
|
'-w' : '--where'}
|
||||||
|
|
||||||
def useopt(option, arg):
|
def useopt(option, arg):
|
||||||
global source
|
global source
|
||||||
global output
|
global output
|
||||||
|
global where
|
||||||
|
global variables
|
||||||
old = None
|
old = None
|
||||||
if option == '--output': old = output; output = arg
|
if option == '--output': old = output; output = arg
|
||||||
elif option == '--source': old = source; source = arg
|
elif option == '--source': old = source; source = arg
|
||||||
|
elif option == '--where': old = where; where = arg
|
||||||
|
elif not option.startswith('-'):
|
||||||
|
if option not in variables:
|
||||||
|
variables[option] = []
|
||||||
|
variables[option].append(arg)
|
||||||
else:
|
else:
|
||||||
raise Exception('Unrecognised option: ' + option)
|
abort('Unrecognised option: ' + option)
|
||||||
if old is not None:
|
if old is not None:
|
||||||
raise Exception('Duplicate option: ' + option)
|
abort('Duplicate option: ' + option)
|
||||||
|
|
||||||
for arg in sys.argv[2:]:
|
for arg in sys.argv[1:]:
|
||||||
if option is not None:
|
if option is not None:
|
||||||
if option in aliases:
|
if option in aliases:
|
||||||
option = aliases[option]
|
option = aliases[option]
|
||||||
useopt(option, arg)
|
useopt(option, arg)
|
||||||
option = None
|
option = None
|
||||||
|
elif (shell is None) and not arg.startswith('-'):
|
||||||
|
shell = arg
|
||||||
else:
|
else:
|
||||||
if '=' in arg:
|
if '=' in arg:
|
||||||
useopt(arg[:index('=')], arg[index('=') + 1:])
|
useopt(arg[:arg.index('=')], arg[arg.index('=') + 1:])
|
||||||
else:
|
else:
|
||||||
option = arg
|
option = arg
|
||||||
|
|
||||||
if output is None: raise Exception('Unused option: --output')
|
if shell is None:
|
||||||
if source is None: raise Exception('Unused option: --source')
|
abort('No shell has been specified')
|
||||||
|
if where is None:
|
||||||
main(shell= shell, output= output, source= source)
|
if output is None: abort('Unused option: --output')
|
||||||
|
if source is None: abort('Unused option: --source')
|
||||||
|
main(shell= shell, output= output, source= source)
|
||||||
|
else:
|
||||||
|
where_main(shell= shell, command= where)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue