diff options
Diffstat (limited to '')
| -rw-r--r-- | info/auto-auto-complete.texinfo | 11 | ||||
| -rwxr-xr-x | src/auto-auto-complete.py | 281 | ||||
| -rw-r--r-- | src/completion | 5 | 
3 files changed, 176 insertions, 121 deletions
| diff --git a/info/auto-auto-complete.texinfo b/info/auto-auto-complete.texinfo index 891a3ed..977769e 100644 --- a/info/auto-auto-complete.texinfo +++ b/info/auto-auto-complete.texinfo @@ -111,6 +111,17 @@ and @code{--file}, add the arguments @option{srcopt=-s},  @option{srcopt=--file}. It is not possible to have  variable whose name begin with a dash (`-'). +Alternatively you can run +@command{auto-auto-complete SHELL --where COMMAND} +(alternatively with @option{-w} instead of +@option{--where}). This will print the pathname +you should use for the generated file when installing +it. However the path prefix will not be included, +so if your package is installed to @file{/usr} +@footnote{The command being installed to @file{/usr/bin} +or @file{/usr/sbin}.}, you sould prepend @file{/usr} +to the output. +  @node Syntax diff --git a/src/auto-auto-complete.py b/src/auto-auto-complete.py index 35d8ab4..1f77fd8 100755 --- a/src/auto-auto-complete.py +++ b/src/auto-auto-complete.py @@ -21,51 +21,51 @@ 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'): +    ''' +    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')) -''' -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'): +    ''' +    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')) -''' -Abort the program - -@param   text:str        Error message -@return  returncode:int  The programs return code -'''  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:      ''' -    Parse a code and return a tree -     -    @param   code:str      The code to parse -    @return  :list<↑|str>  The root node in the tree +    Bracket tree parser      '''      @staticmethod      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 = []          stackptr = -1 @@ -146,13 +146,13 @@ class Parser:          abort('premature end of file') -    ''' -    Simplifies a tree -     -    @param  tree:list<↑|str>  The tree -    '''      @staticmethod      def simplify(tree): +        ''' +        Simplifies a tree +         +        @param  tree:list<↑|str>  The tree +        '''          global variables          program = tree[0]          stack = [tree] @@ -196,21 +196,21 @@ class Parser: -''' -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 +    Completion script generator for GNU Bash      '''      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.unargumented = unargumented          self.argumented   = argumented @@ -219,12 +219,12 @@ class GeneratorBASH:          self.default      = default -    ''' -    Gets the argument suggesters for each option -     -    @return  :dist<str, str>  Map from option to suggester -    '''      def __getSuggesters(self): +        ''' +        Gets the argument suggesters for each option +         +        @return  :dist<str, str>  Map from option to suggester +        '''          suggesters = {}          for group in (self.unargumented, self.argumented, self.variadic): @@ -246,12 +246,12 @@ class GeneratorBASH:          return suggesters -    ''' -    Returns the generated code -     -    @return  :str  The generated code -    '''      def get(self): +        ''' +        Returns the generated code +         +        @return  :str  The generated code +        '''          buf = '# bash completion for %s         -*- shell-script -*-\n\n' % self.program          buf += '_%s()\n{\n' % self.program          buf += '    local cur prev words cword\n' @@ -353,24 +353,29 @@ class GeneratorBASH:          buf += '}\n\ncomplete -o default -F _%s %s\n\n' % (self.program, self.program)          return buf +     +     +    @staticmethod +    def where(command): +        return '/share/bash-completion/completions/%s' % command -''' -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 +    Completion script generator for fish      '''      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.unargumented = unargumented          self.argumented   = argumented @@ -379,12 +384,12 @@ class GeneratorFISH:          self.default      = default -    ''' -    Gets the argument suggesters for each option -     -    @return  :dist<str, str>  Map from option to suggester -    '''      def __getSuggesters(self): +        ''' +        Gets the argument suggesters for each option +         +        @return  :dist<str, str>  Map from option to suggester +        '''          suggesters = {}          for group in (self.unargumented, self.argumented, self.variadic): @@ -406,12 +411,12 @@ class GeneratorFISH:          return suggesters -    ''' -    Gets the file pattern for each option -     -    @return  :dist<str, list<str>>  Map from option to file pattern -    '''      def __getFiles(self): +        ''' +        Gets the file pattern for each option +         +        @return  :dist<str, list<str>>  Map from option to file pattern +        '''          files = {}          for group in (self.unargumented, self.argumented, self.variadic): @@ -433,12 +438,12 @@ class GeneratorFISH:          return files -    ''' -    Returns the generated code -     -    @return  :str  The generated code -    '''      def get(self): +        ''' +        Returns the generated code +         +        @return  :str  The generated code +        '''          buf = '# fish completion for %s         -*- shell-script -*-\n\n' % self.program          files = self.__getFiles() @@ -542,24 +547,29 @@ class GeneratorFISH:                  buf += '\n'          return buf +     +     +    @staticmethod +    def where(command): +        return '/share/fish/completions/%s.fish' % command -''' -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 +    Completion script generator for zsh      '''      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.unargumented = unargumented          self.argumented   = argumented @@ -568,12 +578,12 @@ class GeneratorZSH:          self.default      = default -    ''' -    Gets the argument suggesters for each option -     -    @return  :dist<str, str>  Map from option to suggester -    '''      def __getSuggesters(self): +        ''' +        Gets the argument suggesters for each option +         +        @return  :dist<str, str>  Map from option to suggester +        '''          suggesters = {}          for group in (self.unargumented, self.argumented, self.variadic): @@ -595,12 +605,12 @@ class GeneratorZSH:          return suggesters -    ''' -    Gets the file pattern for each option -     -    @return  :dist<str, list<str>>  Map from option to file pattern -    '''      def __getFiles(self): +        ''' +        Gets the file pattern for each option +         +        @return  :dist<str, list<str>>  Map from option to file pattern +        '''          files = {}          for group in (self.unargumented, self.argumented, self.variadic): @@ -622,12 +632,12 @@ class GeneratorZSH:          return files -    ''' -    Returns the generated code -     -    @return  :str  The generated code -    '''      def get(self): +        ''' +        Returns the generated code +         +        @return  :str  The generated code +        '''          buf = '# zsh completion for %s         -*- shell-script -*-\n\n' % self.program          files = self.__getFiles() @@ -720,17 +730,22 @@ class GeneratorZSH:          buf += '    )\n\n_arguments "$_opts[@]"\n\n'          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): +    ''' +    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:          source = file.read().decode('utf8', 'replace')      source = Parser.parse(source) @@ -776,7 +791,9 @@ def main(shell, output, source):              map[elem[0]] = elem[1:]          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 = generator(program, unargumented, argumented, variadic, suggestion, default)      code = generator.get() @@ -786,31 +803,49 @@ def main(shell, output, source): -''' -mane! -''' +def where_main(shell, command): +    ''' +    --where mane! +     +    @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) < 4: +    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      source = None +    where = None      variables = {}      option = None      aliases = {'-o' : '--output',                 '-f' : '--source', '--file' : '--source', -               '-s' : '--source'} +               '-s' : '--source', +               '-w' : '--where'}      def useopt(option, arg):          global source          global output +        global where          global variables          old = None          if   option == '--output': old = output; output = 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] = [] @@ -834,8 +869,12 @@ if __name__ == '__main__':              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) +    if shell is None: +        abort('No shell has been specified') +    if where is None: +        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) diff --git a/src/completion b/src/completion index 7c16f8a..7e5da65 100644 --- a/src/completion +++ b/src/completion @@ -14,6 +14,11 @@  		    (arg OUTPUT_FILE)  		    (files -f)  		    (desc 'Specify the output shell auto-completion script')) +	(argumented (options -w --where) +		    (complete --where) +		    (arg COMMAND) +		    (files -0) +		    (desc 'Specify a command whose shell auto-completion script path should be printed'))  	(suggestion default (verbatim bash zsh fish VARIABLE=VALUE))  ) | 
