ϪfbdZddlZddlZddlZddlmZddlmZmZm Z ddl m Z m Z m Z ddlmZdZGdd e j"ZGd d ZGd d eZGddZdZdZy)a No public APIs are provided by this module. Internal use only. This module implements dynamic tab-completion for any command that uses twisted.python.usage. Currently, only zsh is supported. Bash support may be added in the future. Maintainer: Eric P. Mangold - twisted AT teratorn DOT org In order for zsh completion to take place the shell must be able to find an appropriate "stub" file ("completion function") that invokes this code and displays the results to the user. The stub used for Twisted commands is in the file C{twisted-completion.zsh}, which is also included in the official Zsh distribution at C{Completion/Unix/Command/_twisted}. Use this file as a basis for completion functions for your own commands. You should only need to change the first line to something like C{#compdef mycommand}. The main public documentation exists in the L{twisted.python.usage.Options} docstring, the L{twisted.python.usage.Completions} docstring, and the Options howto. N) MethodType)DictListSet)reflectusageutil)ioTypec|rt|tk(r |j}|djd\}}t |}|dz}||}|dk\r$||dz j dr|dz}nn|dk\r$|d|}t |dd}|rd} tj||j|j\} }|rT|jD]E\} } } } |d| k(s |d| k(s| }||_ t||||}|jyd }|j drd }t|||}|j| yt|||}|jy#tj$rYwxYw) ao Perform shell completion. A completion function (shell script) is generated for the requested shell and written to C{shellCompFile}, typically C{stdout}. The result is then eval'd by the shell to produce the desired completions. @type config: L{twisted.python.usage.Options} @param config: The L{twisted.python.usage.Options} instance to generate completions for. @type cmdName: C{str} @param cmdName: The name of the command we're generating completions for. In the case of zsh, this is used to print an appropriate "#compdef $CMD" line at the top of the output. This is not necessary for the functionality of the system, but it helps in debugging, since the output we produce is properly formed and may be saved in a file and used as a stand-alone completion function. @type words: C{list} of C{str} @param words: The raw command-line words passed to use by the shell stub function. argv[0] has already been stripped off. @type shellCompFile: C{file} @param shellCompFile: The file to write completion data to. :-N subCommandsrTF)genSubs)r strbuffersplitint startswithgetattrgetoptshortOptlongOpterrorrparentZshSubcommandBuilderwrite ZshBuilder)configcmdNamewords shellCompFile shellNamepositioncWordrargsoptscmdshortparserdoc subOptionsgenrs ;/usr/lib/python3/dist-packages/twisted/python/_shellcomp.py shellCompleter1's> .#5%,,  )//#.Ix8}H MH (OE a- A  ) )# . MH  a- )8 E&-6K ufoov~~NJD$ +1+=+= 'UFC7c>T!W%5!'J(.J%&:"FG]'CIIK    C G-8 ' "-8 7||   s .E$$E:9E:ceZdZdZy)SubcommandActioncF|tjk(rytd|)Nz*::subcmd:->subcmdzUnknown shellType )r_ZSHNotImplementedError)selfoptName shellTypes r0 _shellCodezSubcommandAction._shellCodes$  "'!$6ym"DEEN)__name__ __module__ __qualname__r:r;r0r3r3sFr;r3ceZdZdZdZddZy)r a Constructs zsh code that will complete options for a given usage.Options instance, possibly including a list of subcommand names. Completions for options to subcommands won't be generated because this class will never be used if the user is completing options for a specific subcommand. (See L{ZshSubcommandBuilder} below) @type options: L{twisted.python.usage.Options} @ivar options: The L{twisted.python.usage.Options} instance defined for this command. @type cmdName: C{str} @ivar cmdName: The name of the command we're generating completions for. @type file: C{file} @ivar file: The C{file} to write the completion function to. The C{file} must have L{bytes} I/O semantics. c.||_||_||_yN)optionsr"file)r7rCr"rDs r0__init__zZshBuilder.__init__s   r;c|r.t|jddt|j|j|j}|j j dt|j|jjd|jjD]L\}}}}|jjd|jdzdz|jdzdzN|jjd |jjd yt|j|j|j}|jy) a Generate the completion function and write it to the output file @return: L{None} @type genSubs: C{bool} @param genSubs: Flag indicating whether or not completions for the list of subcommand should be generated. Only has an effect if the C{subCommands} attribute has been defined on the L{twisted.python.usage.Options} instance. rNrs.local _zsh_subcmds_array _zsh_subcmds_array=( "utf-8:s" s) s+_describe "sub-command" _zsh_subcmds_array ) rrCZshArgumentsGeneratorr"rD extraActionsinsertr3rrencode)r7rr/r*r+r,descs r0rzZshBuilder.writes wt||]DAM' dllDIINC    # #A'7'9 : IIK IIOOO P,0LL,D,D (UFD 3::g..5 G8LLvU  IIOOH % IIOOK L' dllDIINC IIKr;N)Tr<r=r>__doc__rErr?r;r0r r s( r;r ceZdZdZdZdZy)ra Constructs zsh code that will complete options for a given usage.Options instance, and also for a single sub-command. This will only be used in the case where the user is completing options for a specific subcommand. @type subOptions: L{twisted.python.usage.Options} @ivar subOptions: The L{twisted.python.usage.Options} instance defined for the sub command. c>||_tj|g|yrB)r.r rE)r7r.r(s r0rEzZshSubcommandBuilder.__init__s$D(4(r;c8t|j|j|j}|jj dt |jt|j|j|j}|jy)zk Generate the completion function and write it to the output file @return: L{None} rN) rJrCr"rDrKrLr3rr.)r7r/s r0rzZshSubcommandBuilder.writesd $DLL$,, J #3#56 #DOOT\\499M r;NrOr?r;r0rrs) r;rc~eZdZdZdZdZdZdZdZdZ dZ dd Z d e e ee ffd Zd Zd ZdZdZddZy)rJa0 Generate a call to the zsh _arguments completion function based on data in a usage.Options instance The first three instance variables are populated based on constructor arguments. The remaining non-constructor variables are populated by this class with data gathered from the C{Options} instance passed in, and its base classes. @type options: L{twisted.python.usage.Options} @ivar options: The L{twisted.python.usage.Options} instance to generate for @type cmdName: C{str} @ivar cmdName: The name of the command we're generating completions for. @type file: C{file} @ivar file: The C{file} to write the completion function to. The C{file} must have L{bytes} I/O semantics. @type descriptions: C{dict} @ivar descriptions: A dict mapping long option names to alternate descriptions. When this variable is defined, the descriptions contained here will override those descriptions provided in the optFlags and optParameters variables. @type multiUse: C{list} @ivar multiUse: An iterable containing those long option names which may appear on the command line more than once. By default, options will only be completed one time. @type mutuallyExclusive: C{list} of C{tuple} @ivar mutuallyExclusive: A sequence of sequences, with each sub-sequence containing those long option names that are mutually exclusive. That is, those options that cannot appear on the command line together. @type optActions: C{dict} @ivar optActions: A dict mapping long option names to shell "actions". These actions define what may be completed as the argument to the given option, and should be given as instances of L{twisted.python.usage.Completer}. Callables may instead be given for the values in this dict. The callable should accept no arguments, and return a C{Completer} instance used as the action. @type extraActions: C{list} of C{twisted.python.usage.Completer} @ivar extraActions: Extra arguments are those arguments typically appearing at the end of the command-line, which are not associated with any particular named option. That is, the arguments that are given to the parseArgs() method of your usage.Options subclass. c||_||_||_i|_t |_g|_i|_g|_ttj|jD]}t|dd}|s|jj|j|jj|j|j j|j |j j|j |js|j|_t j"}g}g}||jd|||jd|t%|D]-\} } t'| dk7st)j*d| || </t%|D]-\} } t'| dk7st)j*d| || </||_||_i} |D] } | dd| | d<| |_i} |D] } | dd| | d<| |_i} | j| | j| | |_|j7|j9|j;|_y)NcompDataoptFlags optParametersrr)rCr"rD descriptionssetmultiUsemutuallyExclusive optActionsrKreversedinspectgetmro __class__rupdateextendraccumulateClassList enumeratelenr padTorW optParamsparamNameToDefinitionflagNameToDefinitionallOptionsNameToDefinitionaddAdditionalOptionsverifyZshNamesmakeExcludesDictexcludes)r7rCr"rDclsdataaCLrWrjioptListrkrlrms r0rEzZshArgumentsGenerator.__init__sc    !#GNN7+<+<=> :C3 D1D!!(():):;&&t7 $$T]]3&&--d.D.DE $$(,(9(9D% :))')(*  G  z84 G   :#H- 5JAw7|q "jjG4  5$I. 6JAw7|q #zz!W5 !  6! " "  ?*D' !!# --/ r;c|j|j|j|jy)zf Write the zsh completion code to the file given to __init__ @return: L{None} N) writeHeader writeExtras writeOptions writeFooterr7s r0rzZshArgumentsGenerator.write\s4    r;cx|jjd|jjdzdzy)z^ This is the start of the code that calls _arguments @return: L{None} s #compdef rHs _arguments -s -A "-*" \ N)rDrr"rMr|s r0rxz!ZshArgumentsGenerator.writeHeaderfs5  4<<..w7 7;* * r;ct|jj}|j|D]}|j |y)z] Write out zsh code for each option in this command @return: L{None} N)listrmkeyssortwriteOpt)r7optNameslongnames r0rzz"ZshArgumentsGenerator.writeOptionspsA 77<<>?   $H MM( # $r;c zt|jD]\}}|jr&|t|jdz k7r t d|j j t|jdtjjd|j j dy)a Write out completion information for extra arguments appearing on the command-line. These are extra positional arguments not associated with a named option. That is, the stuff that gets passed to Options.parseArgs(). @return: L{None} @raise ValueError: If C{Completer} with C{repeat=True} is found and is not the last item in the C{extraActions} list. rzDCompleter with repeat=True must be last item in Options.extraActionsrH \ N) rgrK_repeatrh ValueErrorrDrescaper:rr5rM)r7ruactions r0ryz!ZshArgumentsGenerator.writeExtraszs#4#4#45 &IAv~~!s4+<+<'='A"A 8 IIOOF6#4#4R#DELLWU V IIOOH % &r;c:|jjdy)zj Write the last bit of code that finishes the call to _arguments @return: L{None} s && return 0 N)rDrr|s r0r{z!ZshArgumentsGenerator.writeFooters ()r;cfd}tjjjjD]}|j vs||j D] }|D]}|j vs||"y)z Ensure that none of the option names given in the metadata are typoed @return: L{None} @raise ValueError: If unknown option names have been found. c:td|dj)NzUnknown option name "z1" found while examining Completions instances on )rrC)namer7s r0errz1ZshArgumentsGenerator.verifyZshNames..errs;?O r;N) itertoolschainr[r_r]rmr^)r7rrseqs` r0roz$ZshArgumentsGenerator.verifyZshNamess  OOD$5$5t V D4:::D  )) C t>>>I  r;c||jvr|j|j}n t}||jvr:|dur%|j |}|#|j |n|j ||syg}|D]9}t |dk(r|jd|z&|jd|z;|jddj|zS)a Generate an "exclusion string" for the given option @type longname: C{str} @param longname: The long option name (e.g. "verbose" instead of "v") @type buildShort: C{bool} @param buildShort: May be True to indicate we're building an excludes string for the short option that corresponds to the given long opt. @return: The generated C{str} Frrrz--z(%s) ) rqcopyr\r]getShortOptionaddrhappendrjoin)r7r buildShort exclusionsr+stringsr8s r0 excludeStrz ZshArgumentsGenerator.excludeStrs t}} $x0557JJ 4== (U"++H5$NN5)x(! /G7|q sW}-tg~.  /  )))r;returnci}tj|j|jD]}|ddk7s |d||d<i}|jD]{}t |D]k\}}t |d|||dzdz}|jD]}||vs|j||||vr||j|||<g|||<m}|S)z @return: A C{dict} that maps each option name appearing in self.mutuallyExclusive to a set of those option names that is it mutually exclusive with (can't appear on the cmd line with). rNr) rrrjrWr^rgr\rrunion) r7 longToShortrvrqlstrurtmprs r0rpz&ZshArgumentsGenerator.makeExcludesDicts  t~~t}}E 5GqzT!*1!* GAJ' 5)+)) -C(~ - 8#bq'CAL01HHJ3D{* D 123x')1();)A)A#)FHX&),HX& - -r;c ||jvrd|z}nd|z}|j|}|dk7rd|z}nd}|j|}|jdd}|jdd }d |z}|j |}||j vrd }nd}|j |} |rk|j |d } |jjt| ||||jd|jjd|jjt| ||||jd|jjdy)a Write out the zsh code for the given argument. This is just part of the one big call to _arguments @type longname: C{str} @param longname: The long option name (e.g. "verbose" instead of "v") @return: L{None} z--%sz--%s=Nrr[z\[]z\]z[%s]*T)rrHr) rlrgetDescriptionreplace getActionr]rrDrrrM) r7r longFieldr+ shortFielddescrdescriptionField actionField multiFieldlongExclusionsFieldshortExclusionsFields r0rzZshArgumentsGenerator.writeOptsj t00 0)I(*I##H- D=uJJ##H- ==e4+33C?!$44nnX. t}} $JJ"ooh7 #'??8?#M IIOO-""(#  &/  IIOOH %  ($  fWo  !r;c||jvr\t|j|r|j|}n|j|}|j|tjS||j vrd|dSy)z] Return a zsh "action" string for the given argument @return: C{str} r z:_filesr)r_callabler:rr5rk)r7rrs r0rzZshArgumentsGenerator.getAction4sy t &122242$$Xuzz: : t11 1xj( (r;cP||jvr|j|S |j|d}||S|j dd}t |j d|zd}|t|}||S|S#t$r( |j|d}n#t$rd}YnwxYwYswxYw)z] Return the description to be used for this argument @return: C{str} rrNr_zopt_%s)r[rlKeyErrorrkrrrC descrFromDoc)r7rr longMangledobjs r0rz$ZshArgumentsGenerator.getDescriptionDs t(( ($$X. . --h7:E  L&&sC0 dllH{$:DA ? %E  #  228BB% BB%BB%$B%c2|j|}|dxsdS)z[ Return the short option letter or None @return: C{str} or L{None} rN)rm)r7rrvs r0rz$ZshArgumentsGenerator.getShortOptioncs# 11(;qz!T!r;Nci}tj|j|di}|jD]}t |dk(s||||<||=|j D]\}}|j dd}||jvr'|j|}d}||vr||}|jjj} | dk(rD|jj||d|g|d|g|j|<|d|g|j|<|jj|||g||g|j |<|d|g|j|<y)z Add additional options to the optFlags and optParams lists. These will be defined by 'opt_foo' methods of the Options subclass @return: L{None} opt_rrrNr)raccumulateMethodsrCrrhitemsrrmr__func____code__ co_argcountrjrrkrWrl) r7 methodsDict methodToShortr methodName methodObjrrr+reqArgss r0rnz*ZshArgumentsGenerator.addAdditionalOptionsksx .0 !!$,, VD $$& &D4yA~37 k$/0% & &1%6%6%8 Q !J !))#s3H4:::''1EEM)%i0((11==G!|%%xe&DE8=tU7K**84=BD%7rPrErrxrzryr{rorrrrrprrrrrnr?r;r0rJrJsh2hB0H $&,*,(*T$sCH}"56@"D >"%Qr;rJc|j|jjry|jjdDcgc]&}|s|jr|j(}}dj |Scc}w)zP Generate an appropriate description from docstring of the given object N r)rPisspacerstripr)rxliness r0rrsf {{ckk113 # 1 1$ 7 Q11QYY[QWWY QE Q 88E? RsB BBcVd|vrd|zdzSd}|D]}|dvr|dz}||z}|dz}|S)zw Shell escape the given string Implementation borrowed from now-deprecated commands.mkarg() in the stdlib '"z\$"`\r?)rscs r0rrsV  !|Qw} A  <DA E CA Hr;)rPrrartypesrtypingrrrtwisted.pythonrrr twisted.python.compatr r1 Completerr3r rrJrrr?r;r0rsp 0""//(aHFuF22j:8mQmQ`  r;