From 02e7926c22b4244eb19f0524dc771d55bc552b21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Andr=C3=A9e?= Date: Sat, 17 Aug 2013 22:02:43 +0200 Subject: [PATCH] use auto-auto-complete>=3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- CHANGELOG | 2 + completion/auto-auto-complete.py | 800 ------------------------------- completion/ponysay | 2 +- completion/ponythink | 1 + dependency-test.sh | 18 +- dev/tests/auto-completion | 4 +- dev/tests/auto-completion-tool | 4 +- manuals/ponysay.texinfo | 5 + setup.py | 31 +- 9 files changed, 26 insertions(+), 841 deletions(-) delete mode 100755 completion/auto-auto-complete.py create mode 120000 completion/ponythink diff --git a/CHANGELOG b/CHANGELOG index 91245d22..6b8e8f92 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -36,6 +36,8 @@ Version 3.0.2 +h (++help, --help-colour) added. + auto-auto-complete>=3 added as optional build dependency. + Version 3.0.1 diff --git a/completion/auto-auto-complete.py b/completion/auto-auto-complete.py deleted file mode 100755 index fb599dd6..00000000 --- a/completion/auto-auto-complete.py +++ /dev/null @@ -1,800 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - - -############################################################################################### -## Shell auto-completion script generator https://www.github.com/maandree/auto-auto-complete ## -## Used by build system to make completions for all supported shells. ## -## ## -## auto-auto-complete is experimental, therefore, brefore updating the version of this ## -## make sure that is still work for all shells. ## -############################################################################################### - - -''' -auto-auto-complete – Autogenerate shell auto-completion scripts - -Copyright © 2012 Mattias Andrée (maandree@kth.se) - -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 . -''' -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')) - - - - -''' -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 - - 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 - - raise Exception('premature end of file') - - - ''' - Simplifies a tree - - @param tree:list<↑|str> The tree - ''' - @staticmethod - def simplify(tree): - 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 - 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>> Specification of unargumented options - @param argumented:list>> Specification of argumented options - @param variadic:list>> Specification of variadic options - @param suggestion:list> Specification of argument suggestions - @param default:dict>? 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 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>> Specification of unargumented options - @param argumented:list>> Specification of argumented options - @param variadic:list>> Specification of variadic options - @param suggestion:list> Specification of argument suggestions - @param default:dict>? 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 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> 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>> Specification of unargumented options - @param argumented:list>> Specification of argumented options - @param variadic:list>> Specification of variadic options - @param suggestion:list> Specification of argument suggestions - @param default:dict>? 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 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> 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 in (unargumented, argumented, variadic): - for index in range(0, len(group)): - item = group[index] - map = {} - for elem in item: - map[elem[0]] = elem[1:] - group[index] = map - if default is not None: - map = {} - for elem in default: - 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) != 6: - print("USAGE: auto-auto-complete SHELL --output OUTPUT_FILE --source SOURCE_FILE") - exit(1) - - shell = sys.argv[1] - output = None - source = None - - option = None - aliases = {'-o' : '--output', - '-f' : '--source', '--file' : '--source', - '-s' : '--source'} - - def useopt(option, arg): - global source - global output - old = None - if option == '--output': old = output; output = arg - elif option == '--source': old = source; source = arg - else: - raise Exception('Unrecognised option: ' + option) - if old is not None: - raise Exception('Duplicate option: ' + option) - - for arg in sys.argv[2:]: - if option is not None: - if option in aliases: - option = aliases[option] - useopt(option, arg) - option = None - else: - if '=' in arg: - useopt(arg[:index('=')], arg[index('=') + 1:]) - else: - option = arg - - if output is None: raise Exception('Unused option: --output') - if source is None: raise Exception('Unused option: --source') - - main(shell= shell, output= output, source= source) - diff --git a/completion/ponysay b/completion/ponysay index 8754a981..cfe02978 100644 --- a/completion/ponysay +++ b/completion/ponysay @@ -1,4 +1,4 @@ -(ponysay +((value command) (default (arg MESSAGE) (files -0) (suggest message) (desc 'Message spoken by the pony')) (multiple unargumented diff --git a/completion/ponythink b/completion/ponythink new file mode 120000 index 00000000..31b2aba2 --- /dev/null +++ b/completion/ponythink @@ -0,0 +1 @@ +ponysay \ No newline at end of file diff --git a/dependency-test.sh b/dependency-test.sh index 3e96965f..102a0b8d 100755 --- a/dependency-test.sh +++ b/dependency-test.sh @@ -13,23 +13,25 @@ ro=0 # runtime optional pv=0 # python version -(hash chmod 2>/dev/null) || (br=1 ; ro=1 ; echo 'Missing chmod, install coreutils [build+runtime required]') +(hash chmod 2>/dev/null) || (br=1 ; ro=1 ; echo 'Missing chmod, install coreutils [build required + runtime optional]') -(hash gzip 2>/dev/null) || (bo=1 ; echo 'Missing gzip, install gzip [build optional]') -(hash makeinfo 2>/dev/null) || (bo=1 ; echo 'Missing makeinfo, install texinfo [build optional]') -(hash install-info 2>/dev/null) || (bo=1 ; echo 'Missing install-info, install info [build optional]') +(hash gzip 2>/dev/null) || (bo=1 ; echo 'Missing gzip, install gzip [build optional]') +(hash makeinfo 2>/dev/null) || (bo=1 ; echo 'Missing makeinfo, install texinfo [build optional]') +(hash install-info 2>/dev/null) || (bo=1 ; echo 'Missing install-info, install info [build optional]') -(hash python 2>/dev/null) || (br=1 ; rr=1 ; echo 'Missing python, install python>=3 [build+runtime required]') +(hash auto-auto-complete 2>/dev/null) || (bo=1 ; echo 'Missing auto-auto-complete, install auto-auto-complete>=3 [build optional]') + +(hash python 2>/dev/null) || (br=1 ; rr=1 ; echo 'Missing python, install python>=3 [build+runtime required]') (hash cut 2>/dev/null) && (hash python 2>/dev/null) && (test ! $(env python --version 2>&1 | cut -d ' ' -f 2 | cut -d '.' -f 1) = 3) && ( (hash python3 2>/dev/null) || (br=1 ; rr=1 ; pv=1 ; echo 'Missing python>=3, install python (may be named python3) [build+runtime required]')) -(hash stty 2>/dev/null) || (rr=1 ; echo 'Missing stty, install coreutils [runtime required]') +(hash stty 2>/dev/null) || (rr=1 ; echo 'Missing stty, install coreutils [runtime required]') -(hash ponytool 2>/dev/null) || (ro=1 ; echo 'Missing ponytool, install util-say [runtime optional]') -(hash chmod 2>/dev/null) || (rr=1 ; echo 'Missing chmod, install coreutils [runtime optional]') +(hash ponytool 2>/dev/null) || (ro=1 ; echo 'Missing ponytool, install util-say [runtime optional]') +(hash chmod 2>/dev/null) || (rr=1 ; echo 'Missing chmod, install coreutils [runtime optional]') ( (test $br = 1) || (test $rr = 1) || (test $ro = 1) || (test $pv = 1) ) && echo diff --git a/dev/tests/auto-completion b/dev/tests/auto-completion index 7e1bfeb8..35f6e1da 100755 --- a/dev/tests/auto-completion +++ b/dev/tests/auto-completion @@ -10,13 +10,13 @@ echo $'\e[1m-- Testing that the shell auto-completion script compiles --\e[0m' ## If this automated bisection stops at a commit with a syntax error or other error that cases the test to fail for another reason, ## you will need to manually run bisect, and use `git reset --hard HEAD~1` (or similar) to skip that commit, see `git bisect --help` -if ! ./completion/auto-auto-complete.py bash --source ./completion/ponysay --output /dev/null; then +if ! auto-auto-complete bash --source ./completion/ponysay --output /dev/null; then git bisect start git bisect bad git bisect good e8aa39a810e43866a8cc978a038545949711f999 lastlog="" while true; do - if ! ./completion/auto-auto-complete.py bash --source ./completion/ponysay --output /dev/null; then + if ! auto-auto-complete bash --source ./completion/ponysay --output /dev/null; then git bisect good else git bisect bad diff --git a/dev/tests/auto-completion-tool b/dev/tests/auto-completion-tool index 0ceaf8e7..c9f48aec 100755 --- a/dev/tests/auto-completion-tool +++ b/dev/tests/auto-completion-tool @@ -10,13 +10,13 @@ echo $'\e[1m-- Testing that the shell auto-completion script for ponysay-tool co ## If this automated bisection stops at a commit with a syntax error or other error that cases the test to fail for another reason, ## you will need to manually run bisect, and use `git reset --hard HEAD~1` (or similar) to skip that commit, see `git bisect --help` -if ! ./completion/auto-auto-complete.py bash --source ./completion/ponysay-tool --output /dev/null; then +if ! auto-auto-complete bash --source ./completion/ponysay-tool --output /dev/null; then git bisect start git bisect bad git bisect good e8aa39a810e43866a8cc978a038545949711f999 lastlog="" while true; do - if ! ./completion/auto-auto-complete.py bash --source ./completion/ponysay-tool --output /dev/null; then + if ! auto-auto-complete bash --source ./completion/ponysay-tool --output /dev/null; then git bisect good else git bisect bad diff --git a/manuals/ponysay.texinfo b/manuals/ponysay.texinfo index f5430b09..66d5de2d 100644 --- a/manuals/ponysay.texinfo +++ b/manuals/ponysay.texinfo @@ -1779,6 +1779,9 @@ Used to compile this @command{info} manual. (Optional, standard) @item info@footnote{Normally a part of @command{texinfo}.} Used to install this @command{info} manual with @command{install-info}. (Optional, standard) +@item auto-auto-complete +@pindex @command{auto-auto-complete} +Used to generate shell tab-completion scripts. (Optional, standard) @end table @@ -3292,6 +3295,8 @@ Swedish manual page added. @option{+h} (@option{++help}, @option{--help-colour}) added. @item Added manpage for @command{ponysay-tool}. +@item +@command{auto-auto-complete>=3} added as optional build dependency. @end itemize @heading Version 3.0.1 diff --git a/setup.py b/setup.py index d3d68722..3891980b 100755 --- a/setup.py +++ b/setup.py @@ -468,38 +468,13 @@ class Setup(): ext = conf['pdf-compression'] if ext is not None: compress('ponysay.pdf', 'ponysay.pdf.' + ext, ext) - - for command in commands: - source = 'completion/ponysay' - sourceed = 'completion/ponysay.%s' % (command) - try: - fileout = open(sourceed, 'wb+') - filein = open(source, 'rb') - data = filein.read().decode('utf-8', 'replace') - - if data.startswith('(ponysay\n'): - data = ('(%s ' % command) + data[len('(ponysay\n'):] - elif data.startswith('(ponysay '): - data = ('(%s ' % command) + data[len('(ponysay '):] - elif '\n(ponysay\n' in data: - edpos = data.find('\n(ponysay\n') - data = data[:edpos] + ('\n(%s\n' % command) + data[edpas + len('\n(ponysay\n'):] - elif '\n(ponysay ' in data: - data = data[:edpos] + ('\n(%s ' % command) + data[edpas + len('\n(ponysay '):] - else: - raise Exception('File %s does not look like expected' % source) - - fileout.write(data.encode('utf-8')) - finally: - if fileout is not None: fileout.close() - if filein is not None: filein .close() - + for shell in [item[0] for item in shells]: if conf[shell] is not None: for command in commands: - sourceed = 'completion/ponysay.%s' % (command) + source = 'completion/%s' % command generated = 'completion/%s-completion.%s' % (shell, command) - generatorcmd = './completion/auto-auto-complete.py %s --output %s --source %s' % (shell, generated, sourceed) + generatorcmd = 'auto-auto-complete %s --output %s --source %s command=%s' % (shell, generated, source, command) Popen(generatorcmd.split(' ')).communicate() if conf[command] is not None: dest = generated + '.install'