PNG  IHDRX cHRMz&u0`:pQ<bKGD pHYsodtIME MeqIDATxw]Wug^Qd˶ 6`!N:!@xI~)%7%@Bh&`lnjVF29gΨ4E$|>cɚ{gk= %,a KX%,a KX%,a KX%,a KX%,a KX%,a KX%, b` ǟzeאfp]<!SJmɤY޲ڿ,%c ~ع9VH.!Ͳz&QynֺTkRR.BLHi٪:l;@(!MԴ=žI,:o&N'Kù\vRmJ雵֫AWic H@" !: Cé||]k-Ha oݜ:y F())u]aG7*JV@J415p=sZH!=!DRʯvɱh~V\}v/GKY$n]"X"}t@ xS76^[bw4dsce)2dU0 CkMa-U5tvLƀ~mlMwfGE/-]7XAƟ`׮g ewxwC4\[~7@O-Q( a*XGƒ{ ՟}$_y3tĐƤatgvێi|K=uVyrŲlLӪuܿzwk$m87k( `múcE)"@rK( z4$D; 2kW=Xb$V[Ru819קR~qloѱDyįݎ*mxw]y5e4K@ЃI0A D@"BDk_)N\8͜9dz"fK0zɿvM /.:2O{ Nb=M=7>??Zuo32 DLD@D| &+֎C #B8ַ`bOb $D#ͮҪtx]%`ES`Ru[=¾!@Od37LJ0!OIR4m]GZRJu$‡c=%~s@6SKy?CeIh:[vR@Lh | (BhAMy=݃  G"'wzn޺~8ԽSh ~T*A:xR[ܹ?X[uKL_=fDȊ؂p0}7=D$Ekq!/t.*2ʼnDbŞ}DijYaȲ(""6HA;:LzxQ‘(SQQ}*PL*fc\s `/d'QXW, e`#kPGZuŞuO{{wm[&NBTiiI0bukcA9<4@SӊH*؎4U/'2U5.(9JuDfrޱtycU%j(:RUbArLֺN)udA':uGQN"-"Is.*+k@ `Ojs@yU/ H:l;@yyTn}_yw!VkRJ4P)~y#)r,D =ě"Q]ci'%HI4ZL0"MJy 8A{ aN<8D"1#IJi >XjX֔#@>-{vN!8tRݻ^)N_╗FJEk]CT՟ YP:_|H1@ CBk]yKYp|og?*dGvzنzӴzjֺNkC~AbZƷ`.H)=!QͷVTT(| u78y֮}|[8-Vjp%2JPk[}ԉaH8Wpqhwr:vWª<}l77_~{s۴V+RCģ%WRZ\AqHifɤL36: #F:p]Bq/z{0CU6ݳEv_^k7'>sq*+kH%a`0ԣisqにtү04gVgW΂iJiS'3w.w}l6MC2uԯ|>JF5`fV5m`Y**Db1FKNttu]4ccsQNnex/87+}xaUW9y>ͯ骵G{䩓Գ3+vU}~jJ.NFRD7<aJDB1#ҳgSb,+CS?/ VG J?|?,2#M9}B)MiE+G`-wo߫V`fio(}S^4e~V4bHOYb"b#E)dda:'?}׮4繏`{7Z"uny-?ǹ;0MKx{:_pÚmFמ:F " .LFQLG)Q8qN q¯¯3wOvxDb\. BKD9_NN &L:4D{mm o^tֽ:q!ƥ}K+<"m78N< ywsard5+вz~mnG)=}lYݧNj'QJS{S :UYS-952?&O-:W}(!6Mk4+>A>j+i|<<|;ر^߉=HE|V#F)Emm#}/"y GII웻Jі94+v뾧xu~5C95~ūH>c@덉pʃ1/4-A2G%7>m;–Y,cyyaln" ?ƻ!ʪ<{~h~i y.zZB̃/,雋SiC/JFMmBH&&FAbϓO^tubbb_hZ{_QZ-sύodFgO(6]TJA˯#`۶ɟ( %$&+V'~hiYy>922 Wp74Zkq+Ovn錄c>8~GqܲcWꂎz@"1A.}T)uiW4="jJ2W7mU/N0gcqܗOO}?9/wìXžΏ0 >֩(V^Rh32!Hj5`;O28؇2#ݕf3 ?sJd8NJ@7O0 b־?lldщ̡&|9C.8RTWwxWy46ah嘦mh٤&l zCy!PY?: CJyв]dm4ǜҐR޻RլhX{FƯanшQI@x' ao(kUUuxW_Ñ줮[w8 FRJ(8˼)_mQ _!RJhm=!cVmm ?sFOnll6Qk}alY}; "baӌ~M0w,Ggw2W:G/k2%R,_=u`WU R.9T"v,<\Ik޽/2110Ӿxc0gyC&Ny޽JҢrV6N ``یeA16"J³+Rj*;BϜkZPJaÍ<Jyw:NP8/D$ 011z֊Ⱳ3ι֘k1V_"h!JPIΣ'ɜ* aEAd:ݺ>y<}Lp&PlRfTb1]o .2EW\ͮ]38؋rTJsǏP@芎sF\> P^+dYJLbJ C-xϐn> ι$nj,;Ǖa FU *择|h ~izť3ᤓ`K'-f tL7JK+vf2)V'-sFuB4i+m+@My=O҈0"|Yxoj,3]:cо3 $#uŘ%Y"y죯LebqtҢVzq¼X)~>4L׶m~[1_k?kxֺQ`\ |ٛY4Ѯr!)N9{56(iNq}O()Em]=F&u?$HypWUeB\k]JɩSع9 Zqg4ZĊo oMcjZBU]B\TUd34ݝ~:7ڶSUsB0Z3srx 7`:5xcx !qZA!;%͚7&P H<WL!džOb5kF)xor^aujƍ7 Ǡ8/p^(L>ὴ-B,{ۇWzֺ^k]3\EE@7>lYBȝR.oHnXO/}sB|.i@ɥDB4tcm,@ӣgdtJ!lH$_vN166L__'Z)y&kH;:,Y7=J 9cG) V\hjiE;gya~%ks_nC~Er er)muuMg2;֫R)Md) ,¶ 2-wr#F7<-BBn~_(o=KO㭇[Xv eN_SMgSҐ BS헃D%g_N:/pe -wkG*9yYSZS.9cREL !k}<4_Xs#FmҶ:7R$i,fi!~' # !6/S6y@kZkZcX)%5V4P]VGYq%H1!;e1MV<!ϐHO021Dp= HMs~~a)ަu7G^];git!Frl]H/L$=AeUvZE4P\.,xi {-~p?2b#amXAHq)MWǾI_r`S Hz&|{ +ʖ_= (YS(_g0a03M`I&'9vl?MM+m~}*xT۲(fY*V4x@29s{DaY"toGNTO+xCAO~4Ϳ;p`Ѫ:>Ҵ7K 3}+0 387x\)a"/E>qpWB=1 ¨"MP(\xp߫́A3+J] n[ʼnӼaTbZUWb={~2ooKױӰp(CS\S筐R*JغV&&"FA}J>G֐p1ٸbk7 ŘH$JoN <8s^yk_[;gy-;߉DV{c B yce% aJhDȶ 2IdйIB/^n0tNtџdcKj4϶v~- CBcgqx9= PJ) dMsjpYB] GD4RDWX +h{y`,3ꊕ$`zj*N^TP4L:Iz9~6s) Ga:?y*J~?OrMwP\](21sZUD ?ܟQ5Q%ggW6QdO+\@ ̪X'GxN @'4=ˋ+*VwN ne_|(/BDfj5(Dq<*tNt1х!MV.C0 32b#?n0pzj#!38}޴o1KovCJ`8ŗ_"]] rDUy޲@ Ȗ-;xџ'^Y`zEd?0„ DAL18IS]VGq\4o !swV7ˣι%4FѮ~}6)OgS[~Q vcYbL!wG3 7띸*E Pql8=jT\꘿I(z<[6OrR8ºC~ډ]=rNl[g|v TMTղb-o}OrP^Q]<98S¤!k)G(Vkwyqyr޽Nv`N/e p/~NAOk \I:G6]4+K;j$R:Mi #*[AȚT,ʰ,;N{HZTGMoּy) ]%dHء9Պ䠬|<45,\=[bƟ8QXeB3- &dҩ^{>/86bXmZ]]yޚN[(WAHL$YAgDKp=5GHjU&99v簪C0vygln*P)9^͞}lMuiH!̍#DoRBn9l@ xA/_v=ȺT{7Yt2N"4!YN`ae >Q<XMydEB`VU}u]嫇.%e^ánE87Mu\t`cP=AD/G)sI"@MP;)]%fH9'FNsj1pVhY&9=0pfuJ&gޤx+k:!r˭wkl03׼Ku C &ѓYt{.O.zҏ z}/tf_wEp2gvX)GN#I ݭ߽v/ .& и(ZF{e"=V!{zW`, ]+LGz"(UJp|j( #V4, 8B 0 9OkRrlɱl94)'VH9=9W|>PS['G(*I1==C<5"Pg+x'K5EMd؞Af8lG ?D FtoB[je?{k3zQ vZ;%Ɠ,]E>KZ+T/ EJxOZ1i #T<@ I}q9/t'zi(EMqw`mYkU6;[t4DPeckeM;H}_g pMww}k6#H㶏+b8雡Sxp)&C $@'b,fPߑt$RbJ'vznuS ~8='72_`{q纶|Q)Xk}cPz9p7O:'|G~8wx(a 0QCko|0ASD>Ip=4Q, d|F8RcU"/KM opKle M3#i0c%<7׿p&pZq[TR"BpqauIp$ 8~Ĩ!8Սx\ւdT>>Z40ks7 z2IQ}ItԀ<-%S⍤};zIb$I 5K}Q͙D8UguWE$Jh )cu4N tZl+[]M4k8֦Zeq֮M7uIqG 1==tLtR,ƜSrHYt&QP윯Lg' I,3@P'}'R˪e/%-Auv·ñ\> vDJzlӾNv5:|K/Jb6KI9)Zh*ZAi`?S {aiVDԲuy5W7pWeQJk֤#5&V<̺@/GH?^τZL|IJNvI:'P=Ϛt"¨=cud S Q.Ki0 !cJy;LJR;G{BJy޺[^8fK6)=yʊ+(k|&xQ2`L?Ȓ2@Mf 0C`6-%pKpm')c$׻K5[J*U[/#hH!6acB JA _|uMvDyk y)6OPYjœ50VT K}cǻP[ $:]4MEA.y)|B)cf-A?(e|lɉ#P9V)[9t.EiQPDѠ3ϴ;E:+Օ t ȥ~|_N2,ZJLt4! %ա]u {+=p.GhNcŞQI?Nd'yeh n7zi1DB)1S | S#ًZs2|Ɛy$F SxeX{7Vl.Src3E℃Q>b6G ўYCmtկ~=K0f(=LrAS GN'ɹ9<\!a`)֕y[uՍ[09` 9 +57ts6}b4{oqd+J5fa/,97J#6yν99mRWxJyѡyu_TJc`~W>l^q#Ts#2"nD1%fS)FU w{ܯ R{ ˎ󅃏џDsZSQS;LV;7 Od1&1n$ N /.q3~eNɪ]E#oM~}v֯FڦwyZ=<<>Xo稯lfMFV6p02|*=tV!c~]fa5Y^Q_WN|Vs 0ҘދU97OI'N2'8N֭fgg-}V%y]U4 峧p*91#9U kCac_AFңĪy뚇Y_AiuYyTTYЗ-(!JFLt›17uTozc. S;7A&&<ԋ5y;Ro+:' *eYJkWR[@F %SHWP 72k4 qLd'J "zB6{AC0ƁA6U.'F3:Ȅ(9ΜL;D]m8ڥ9}dU "v!;*13Rg^fJyShyy5auA?ɩGHRjo^]׽S)Fm\toy 4WQS@mE#%5ʈfFYDX ~D5Ϡ9tE9So_aU4?Ѽm%&c{n>.KW1Tlb}:j uGi(JgcYj0qn+>) %\!4{LaJso d||u//P_y7iRJ߬nHOy) l+@$($VFIQ9%EeKʈU. ia&FY̒mZ=)+qqoQn >L!qCiDB;Y<%} OgBxB!ØuG)WG9y(Ą{_yesuZmZZey'Wg#C~1Cev@0D $a@˲(.._GimA:uyw֬%;@!JkQVM_Ow:P.s\)ot- ˹"`B,e CRtaEUP<0'}r3[>?G8xU~Nqu;Wm8\RIkբ^5@k+5(By'L&'gBJ3ݶ!/㮻w҅ yqPWUg<e"Qy*167΃sJ\oz]T*UQ<\FԎ`HaNmڜ6DysCask8wP8y9``GJ9lF\G g's Nn͵MLN֪u$| /|7=]O)6s !ĴAKh]q_ap $HH'\1jB^s\|- W1:=6lJBqjY^LsPk""`]w)󭃈,(HC ?䔨Y$Sʣ{4Z+0NvQkhol6C.婧/u]FwiVjZka&%6\F*Ny#8O,22+|Db~d ~Çwc N:FuuCe&oZ(l;@ee-+Wn`44AMK➝2BRՈt7g*1gph9N) *"TF*R(#'88pm=}X]u[i7bEc|\~EMn}P瘊J)K.0i1M6=7'_\kaZ(Th{K*GJyytw"IO-PWJk)..axӝ47"89Cc7ĐBiZx 7m!fy|ϿF9CbȩV 9V-՛^pV̌ɄS#Bv4-@]Vxt-Z, &ֺ*diؠ2^VXbs֔Ìl.jQ]Y[47gj=幽ex)A0ip׳ W2[ᎇhuE^~q흙L} #-b۸oFJ_QP3r6jr+"nfzRJTUqoaۍ /$d8Mx'ݓ= OՃ| )$2mcM*cЙj}f };n YG w0Ia!1Q.oYfr]DyISaP}"dIӗթO67jqR ҊƐƈaɤGG|h;t]䗖oSv|iZqX)oalv;۩meEJ\!8=$4QU4Xo&VEĊ YS^E#d,yX_> ۘ-e\ "Wa6uLĜZi`aD9.% w~mB(02G[6y.773a7 /=o7D)$Z 66 $bY^\CuP. (x'"J60׿Y:Oi;F{w佩b+\Yi`TDWa~|VH)8q/=9!g߆2Y)?ND)%?Ǐ`k/sn:;O299yB=a[Ng 3˲N}vLNy;*?x?~L&=xyӴ~}q{qE*IQ^^ͧvü{Huu=R|>JyUlZV, B~/YF!Y\u_ݼF{_C)LD]m {H 0ihhadd nUkf3oٺCvE\)QJi+֥@tDJkB$1!Đr0XQ|q?d2) Ӣ_}qv-< FŊ߫%roppVBwü~JidY4:}L6M7f٬F "?71<2#?Jyy4뷢<_a7_=Q E=S1И/9{+93֮E{ǂw{))?maÆm(uLE#lïZ  ~d];+]h j?!|$F}*"4(v'8s<ŏUkm7^7no1w2ؗ}TrͿEk>p'8OB7d7R(A 9.*Mi^ͳ; eeUwS+C)uO@ =Sy]` }l8^ZzRXj[^iUɺ$tj))<sbDJfg=Pk_{xaKo1:-uyG0M ԃ\0Lvuy'ȱc2Ji AdyVgVh!{]/&}}ċJ#%d !+87<;qN޼Nفl|1N:8ya  8}k¾+-$4FiZYÔXk*I&'@iI99)HSh4+2G:tGhS^繿 Kتm0 вDk}֚+QT4;sC}rՅE,8CX-e~>G&'9xpW,%Fh,Ry56Y–hW-(v_,? ; qrBk4-V7HQ;ˇ^Gv1JVV%,ik;D_W!))+BoS4QsTM;gt+ndS-~:11Sgv!0qRVh!"Ȋ(̦Yl.]PQWgٳE'`%W1{ndΗBk|Ž7ʒR~,lnoa&:ü$ 3<a[CBݮwt"o\ePJ=Hz"_c^Z.#ˆ*x z̝grY]tdkP*:97YľXyBkD4N.C_[;F9`8& !AMO c `@BA& Ost\-\NX+Xp < !bj3C&QL+*&kAQ=04}cC!9~820G'PC9xa!w&bo_1 Sw"ܱ V )Yl3+ס2KoXOx]"`^WOy :3GO0g;%Yv㐫(R/r (s } u B &FeYZh0y> =2<Ϟc/ -u= c&׭,.0"g"7 6T!vl#sc>{u/Oh Bᾈ)۴74]x7 gMӒ"d]U)}" v4co[ ɡs 5Gg=XR14?5A}D "b{0$L .\4y{_fe:kVS\\O]c^W52LSBDM! C3Dhr̦RtArx4&agaN3Cf<Ԉp4~ B'"1@.b_/xQ} _߃҉/gٓ2Qkqp0շpZ2fԫYz< 4L.Cyυι1t@鎫Fe sYfsF}^ V}N<_`p)alٶ "(XEAVZ<)2},:Ir*#m_YӼ R%a||EƼIJ,,+f"96r/}0jE/)s)cjW#w'Sʯ5<66lj$a~3Kʛy 2:cZ:Yh))+a߭K::N,Q F'qB]={.]h85C9cr=}*rk?vwV렵ٸW Rs%}rNAkDv|uFLBkWY YkX מ|)1!$#3%y?pF<@<Rr0}: }\J [5FRxY<9"SQdE(Q*Qʻ)q1E0B_O24[U'],lOb ]~WjHޏTQ5Syu wq)xnw8~)c 쫬gٲߠ H% k5dƝk> kEj,0% b"vi2Wس_CuK)K{n|>t{P1򨾜j>'kEkƗBg*H%'_aY6Bn!TL&ɌOb{c`'d^{t\i^[uɐ[}q0lM˕G:‚4kb祔c^:?bpg… +37stH:0}en6x˟%/<]BL&* 5&fK9Mq)/iyqtA%kUe[ڛKN]Ě^,"`/ s[EQQm?|XJ߅92m]G.E΃ח U*Cn.j_)Tѧj̿30ڇ!A0=͜ar I3$C^-9#|pk!)?7.x9 @OO;WƝZBFU keZ75F6Tc6"ZȚs2y/1 ʵ:u4xa`C>6Rb/Yм)^=+~uRd`/|_8xbB0?Ft||Z\##|K 0>>zxv8۴吅q 8ĥ)"6>~\8:qM}#͚'ĉ#p\׶ l#bA?)|g g9|8jP(cr,BwV (WliVxxᡁ@0Okn;ɥh$_ckCgriv}>=wGzβ KkBɛ[˪ !J)h&k2%07δt}!d<9;I&0wV/ v 0<H}L&8ob%Hi|޶o&h1L|u֦y~󛱢8fٲUsւ)0oiFx2}X[zVYr_;N(w]_4B@OanC?gĦx>мgx>ΛToZoOMp>40>V Oy V9iq!4 LN,ˢu{jsz]|"R޻&'ƚ{53ўFu(<٪9:΋]B;)B>1::8;~)Yt|0(pw2N%&X,URBK)3\zz&}ax4;ǟ(tLNg{N|Ǽ\G#C9g$^\}p?556]/RP.90 k,U8/u776s ʪ_01چ|\N 0VV*3H鴃J7iI!wG_^ypl}r*jɤSR 5QN@ iZ#1ٰy;_\3\BQQ x:WJv츟ٯ$"@6 S#qe딇(/P( Dy~TOϻ<4:-+F`0||;Xl-"uw$Цi󼕝mKʩorz"mϺ$F:~E'ҐvD\y?Rr8_He@ e~O,T.(ފR*cY^m|cVR[8 JҡSm!ΆԨb)RHG{?MpqrmN>߶Y)\p,d#xۆWY*,l6]v0h15M˙MS8+EdI='LBJIH7_9{Caз*Lq,dt >+~ّeʏ?xԕ4bBAŚjﵫ!'\Ը$WNvKO}ӽmSşذqsOy?\[,d@'73'j%kOe`1.g2"e =YIzS2|zŐƄa\U,dP;jhhhaxǶ?КZ՚.q SE+XrbOu%\GتX(H,N^~]JyEZQKceTQ]VGYqnah;y$cQahT&QPZ*iZ8UQQM.qo/T\7X"u?Mttl2Xq(IoW{R^ ux*SYJ! 4S.Jy~ BROS[V|žKNɛP(L6V^|cR7i7nZW1Fd@ Ara{詑|(T*dN]Ko?s=@ |_EvF]׍kR)eBJc" MUUbY6`~V޴dJKß&~'d3i WWWWWW
Current Directory: /usr/share/bash-completion/completions
Viewing File: /usr/share/bash-completion/completions/svn
# ------------------------------------------------------------ # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # ------------------------------------------------------------ # Programmable completion for the Subversion svn command under bash. Source # this file (or on some systems add it to ~/.bash_completion and start a new # shell) and bash's completion mechanism will know all about svn's options! # Provides completion for the svnadmin, svndumpfilter, svnlook and svnsync # commands as well. Who wants to read man pages/help text... # Known to work with bash 3.* with programmable completion and extended # pattern matching enabled (use 'shopt -s extglob progcomp' to enable # these if they are not already enabled). shopt -s extglob # Tree helper functions which only use bash, to ease readability. # look for value associated to key from stdin in K/V hash file format # val=$(_svn_read_hashfile svn:realmstring < some/file) function _svn_read_hashfile() { local tkey=$1 key= val= while true; do read tag len [ $tag = 'END' ] && break [ $tag != 'K' ] && { #echo "unexpected tag '$tag' instead of 'K'" >&2 return } read -r -n $len key ; read read tag len [ $tag != 'V' ] && { #echo "unexpected tag '$tag' instead of 'V'" >&2 return } read -r -n $len val ; read if [[ $key = $tkey ]] ; then echo "$val" return fi done #echo "target key '$tkey' not found" >&2 } # _svn_grcut shell-regular-expression # extract filenames from 'svn status' output function _svn_grcut() { local re=$1 line= old_IFS # fix IFS, so that leading spaces are not ignored by next read. # (there is a leading space in svn status output if only a prop is changed) old_IFS="$IFS" IFS=$'\n' while read -r line ; do [[ ! $re || $line == $re ]] && echo "${line/????????/}" done IFS="$old_IFS" } # extract stuff from svn info output # _svn_info (URL|Repository Root) function _svn_info() { local what=$1 line= LANG=C LC_MESSAGES=C svn info --non-interactive 2> /dev/null | \ while read line ; do [[ $line == *"$what: "* ]] && echo ${line#*: } done } # _svn_lls (dir|file|all) files... # list svn-managed files from list # some 'svn status --all-files' would be welcome here? function _svn_lls() { local opt=$1 f= shift for f in "$@" ; do # could try to check in .svn/entries? hmmm... if [[ $opt == @(dir|all) && -d "$f" ]] ; then echo "$f/" elif [[ $opt == @(file|all) ]] ; then # split f in directory/file names local dn= fn="$f" [[ "$f" == */* ]] && dn=${f%\/*}/ fn=${f##*\/} # ??? this does not work for just added files, because they # do not have a content reference yet... [ -f "${dn}.svn/text-base/${fn}.svn-base" ] && echo "$f" fi done } # This completion guides the command/option order along the one suggested # by "svn help", although other syntaxes are allowed. # # - there is a "real" parser to check for what is available and deduce what # can be suggested further. # - the syntax should be coherent with subversion/svn/{cl.h,main.c} # - although it is not a good practice, mixed options and arguments # is supported by the completion as it is by the svn command. # - the completion works in the middle of a line, # but not really in the middle of an argument or option. # - property names are completed: see comments about issues related to handling # ":" within property names although it is a word completion separator. # - unknown properties are assumed to be simple file properties. # - --revprop and --revision options are forced to revision properties # as they are mandatory in this case. # - argument values are suggested to some other options, eg directory names # for --config-dir. # - values for some options can be extended with environment variables: # SVN_BASH_FILE_PROPS: other properties on files/directories # SVN_BASH_REV_PROPS: other properties on revisions # SVN_BASH_ENCODINGS: encodings to be suggested # SVN_BASH_MIME_TYPE: mime types to be suggested # SVN_BASH_KEYWORDS: "svn:keywords" substitutions to be suggested # SVN_BASH_USERNAME: usernames suggested for --username # SVN_BASH_COMPL_EXT: completion extensions for file arguments, based on the # current subcommand, so that for instance only modified files are # suggested for 'revert', only not svn-managed files for 'add', and so on. # Possible values are: # - username: guess usernames from ~/.subversion/auth/... # - urls: guess urls from ~/.subversion/auth/... or others # - svnstatus: use 'svn status' for completion # - recurse: allow recursion (expensive) # - externals: recurse into externals (very expensive) # Former options are reasonable, but beware that both later options # may be unadvisable if used on large working copies. # None of these costly completions are activated by default. # Argument completion outside a working copy results in an error message. # Filenames with spaces are not completed properly. # # TODO # - other options? # - obsolete options could be removed from auto-comp? (e.g. -N) # - obsolete commands could be removed? (e.g. resolved) # - completion does not work properly when editing in the middle of the line # status/previous are those at the end of the line, not at the entry position # - url completion should select more cases where it is relevant # - url completion of http:// schemas could suggest sub directories? # - add completion for experimental 'obliterate' feature? _svn() { local cur cmds cmdOpts pOpts mOpts rOpts qOpts nOpts optsParam opt COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} # Possible expansions, without pure-prefix abbreviations such as "up". cmds='add blame annotate praise cat changelist cl checkout co cleanup' cmds="$cmds commit ci copy cp delete remove rm diff export help import" cmds="$cmds info list ls lock log merge mergeinfo mkdir move mv rename" cmds="$cmds patch propdel pdel propedit pedit propget pget proplist" cmds="$cmds plist propset pset relocate resolve resolved revert status" cmds="$cmds switch unlock update upgrade" # help options have a strange command status... local helpOpts='--help -h' # all special options that have a command status local specOpts="--version $helpOpts" # options that require a parameter # note: continued lines must end '|' continuing lines must start '|' optsParam="-r|--revision|--username|--password|--targets" optsParam="$optsParam|-x|--extensions|-m|--message|-F|--file" optsParam="$optsParam|--encoding|--diff-cmd|--diff3-cmd|--editor-cmd" optsParam="$optsParam|--old|--new|--config-dir|--config-option" optsParam="$optsParam|--native-eol|-l|--limit|-c|--change" optsParam="$optsParam|--depth|--set-depth|--with-revprop" optsParam="$optsParam|--cl|--changelist|--accept|--show-revs" # svn:* and other (env SVN_BASH_*_PROPS) properties local svnProps revProps allProps psCmds propCmds # svn and user configured "file" (or directory) properties # the "svn:mergeinfo" prop is not included by default because it is # managed automatically, so there should be no need to edit it by hand. svnProps="svn:keywords svn:executable svn:needs-lock svn:externals svn:ignore svn:eol-style svn:mime-type $SVN_BASH_FILE_PROPS" # svn and user configured revision properties revProps="svn:author svn:log svn:date $SVN_BASH_REV_PROPS" # all properties as an array variable allProps=( $svnProps $revProps ) # subcommands that expect property names psCmds='propset|pset|ps' propCmds="$psCmds|propget|pget|pg|propedit|pedit|pe|propdel|pdel|pd" # possible URL schemas to access a subversion server local urlSchemas='file:/// http:// https:// svn:// svn+ssh://' # Parse arguments and set various variables about what was found. # # cmd: the current command if available # isPropCmd: whether it expects a property name argument # isPsCmd: whether it also expects a property value argument # isHelpCmd: whether it is about help # nExpectArgs: how many arguments are expected by the command # help: help requested about this command (if cmd=='help') # prop: property name (if appropriate) # isRevProp: is it a special revision property # val: property value (if appropriate, under pset) # options: all options encountered # hasRevPropOpt: is --revprop set # hasRevisionOpt: is --revision set # hasRelocateOpt: is --relocate set # hasReintegrateOpt: is --reintegrate set # acceptOpt: the value of --accept # nargs: how many arguments were found # stat: status of parsing at the 'current' word # # prev: previous command in the loop # last: status of last parameter analyzed # i: index local cmd= isPropCmd= isPsCmd= isHelpCmd= nExpectArgs= isCur= i=0 local prev= help= prop= val= isRevProp= last='none' nargs=0 stat= local options= hasRevPropOpt= hasRevisionOpt= hasRelocateOpt= local acceptOpt= URL= hasReintegrateOpt= for opt in "${COMP_WORDS[@]}" do # get status of current word (from previous iteration) [[ $isCur ]] && stat=$last # are we processing the current word isCur= [[ $i -eq $COMP_CWORD ]] && isCur=1 let i++ # FIRST must be the "svn" command [ $last = 'none' ] && { last='first'; continue ; } # SKIP option arguments if [[ $prev == @($optsParam) ]] ; then # record accept value [[ $prev = '--accept' ]] && acceptOpt=$opt prev='' last='skip' continue ; fi # Argh... This looks like a bash bug... # Redirections are passed to the completion function # although it is managed by the shell directly... # It matters because we want to tell the user when no more # completion is available, so it does not necessary # fallback to the default case. if [[ $prev == @(<|>|>>|[12]>|[12]>>) ]] ; then prev='' last='skip' continue ; fi prev=$opt # get the subCoMmanD if [[ ! $cmd && $opt \ && ( $opt != -* || $opt == @(${specOpts// /|}) ) ]] then cmd=$opt [[ $cmd == @($propCmds) ]] && isPropCmd=1 [[ $cmd == @($psCmds) ]] && isPsCmd=1 [[ $cmd == @(${helpOpts// /|}) ]] && cmd='help' [[ $cmd = 'help' ]] && isHelpCmd=1 # HELP about a command asked with an option if [[ $isHelpCmd && $cmd && $cmd != 'help' && ! $help ]] then help=$cmd cmd='help' fi last='cmd' continue fi # HELP about a command if [[ $isHelpCmd && ! $help && $opt && $opt != -* ]] then help=$opt last='help' continue fi # PROPerty name if [[ $isPropCmd && ! $prop && $opt && $opt != -* ]] then prop=$opt [[ $prop == @(${revProps// /|}) ]] && isRevProp=1 last='prop' continue fi # property VALue if [[ $isPsCmd && $prop && ! $val && $opt != -* ]] ; then val=$opt last='val' continue fi if [[ $last != 'onlyarg' ]] then # more OPTions case $opt in -r|--revision|--revision=*) hasRevisionOpt=1 ;; --revprop) hasRevPropOpt=1 # restrict to revision properties! allProps=( $revProps ) # on revprops, only one URL is expected nExpectArgs=1 ;; -h|--help) isHelpCmd=1 ;; -F|--file) val='-F' ;; --relocate) hasRelocateOpt=1 ;; --reintegrate) hasReintegrateOpt=1 ;; esac # no more options, only arguments, whatever they look like. if [[ $opt = '--' && ! $isCur ]] ; then last='onlyarg' continue fi # options are recorded... if [[ $opt == -* ]] ; then # but not the current one! [[ ! $isCur ]] && options="$options $opt " last='opt' continue fi else # onlyarg let nargs++ continue fi # then we have an argument if [[ $cmd = 'merge' && ! $URL ]] ; then # fist argument is the source URL for the merge URL=$opt fi last='arg' let nargs++ done # end opt option processing... [[ $stat ]] || stat=$last # suggest all subcommands, including special help if [[ ! $cmd || $stat = 'cmd' ]] then COMPREPLY=( $( compgen -W "$cmds $specOpts" -- $cur ) ) return 0 fi # suggest all subcommands if [[ $stat = 'help' || ( $isHelpCmd && ! $help ) ]] then COMPREPLY=( $( compgen -W "$cmds" -- $cur ) ) return 0 fi # URL completion if [[ $cmd == @(co|checkout|ls|list) && $stat = 'arg' && \ $SVN_BASH_COMPL_EXT == *urls* ]] then # see about COMP_WORDBREAKS workaround in prop completion if [[ $cur == file:* ]] then # file completion for file:// urls local where=${cur/file:/} COMPREPLY=( $(compgen -d -S '/' -X '*/.*' -- $where ) ) return elif [[ $cur == *:* ]] then # get known urls local urls= file= for file in ~/.subversion/auth/svn.simple/* ; do if [ -r $file ] ; then local url=$(_svn_read_hashfile svn:realmstring < $file) url=${url/*</} url=${url/>*/} urls="$urls $url" fi done # only suggest/show possible suffixes local prefix=${cur%:*} suffix=${cur#*:} c= choices= for c in $urls ; do [[ $c == $prefix:* ]] && choices="$choices ${c#*:}" done COMPREPLY=( $(compgen -W "$choices" -- $suffix ) ) return else # show schemas COMPREPLY=( $(compgen -W "$urlSchemas" -- $cur) ) return fi fi if [[ $cmd = 'merge' || $cmd = 'mergeinfo' ]] then local here=$(_svn_info URL) # suggest a possible URL for merging if [[ ! $URL && $stat = 'arg' ]] ; then # we assume a 'standard' repos with branches and trunk if [[ "$here" == */branches/* ]] ; then # we guess that it is a merge from the trunk COMPREPLY=( $(compgen -W ${here/\/branches\/*/\/trunk} -- $cur ) ) return 0 elif [[ "$here" == */trunk* ]] ; then # we guess that it is a merge from a branch COMPREPLY=( $(compgen -W ${here/\/trunk*/\/branches\/} -- $cur ) ) return 0 else # no se, let us suggest the repository root... COMPREPLY=( $(compgen -W $(_svn_info Root) -- $cur ) ) return 0 fi elif [[ $URL == */branches/* && $here == */trunk* && \ ! $hasReintegrateOpt && $cur = '' && $stat = 'arg' ]] ; then # force --reintegrate only if the current word is empty COMPREPLY=( $(compgen -W '--reintegrate' -- $cur ) ) return 0 fi fi # help about option arguments if [[ $stat = 'skip' ]] then local previous=${COMP_WORDS[COMP_CWORD-1]} local values= dirs= beep= exes= [[ $previous = '--config-dir' ]] && dirs=1 # external editor, diff, diff3... [[ $previous = --*-cmd ]] && exes=1 [[ $previous = '--native-eol' ]] && values='LF CR CRLF' # just to suggest that a number is expected. hummm. [[ $previous = '--limit' ]] && values='0 1 2 3 4 5 6 7 8 9' # some special partial help about --revision option. [[ $previous = '--revision' || $previous = '-r' ]] && \ values='HEAD BASE PREV COMMITTED 0 {' [[ $previous = '--encoding' ]] && \ values="latin1 utf8 $SVN_BASH_ENCODINGS" [[ $previous = '--extensions' || $previous = '-x' ]] && \ values="--unified --ignore-space-change \ --ignore-all-space --ignore-eol-style" [[ $previous = '--depth' ]] && \ values='empty files immediates infinity' [[ $previous = '--set-depth' ]] && \ values='empty exclude files immediates infinity' [[ $previous = '--accept' ]] && \ { # the list is different for 'resolve' if [[ $cmd = 'resolve' ]] ; then # from svn help resolve values='base working mine-full theirs-full' else # checkout merge switch update # not implemented yet: mine-conflict theirs-conflict values='postpone base mine-full theirs-full edit launch' fi } [[ $previous = '--show-revs' ]] && values='merged eligible' if [[ $previous = '--username' ]] ; then values="$SVN_BASH_USERNAME" if [[ $SVN_BASH_COMPL_EXT == *username* ]] ; then local file= # digest? others? for file in ~/.subversion/auth/svn.simple/* ; do if [ -r $file ] ; then values="$values $(_svn_read_hashfile username < $file)" fi done fi [[ ! "$values" ]] && beep=1 fi # could look at ~/.subversion/ ? # hmmm... this option should not exist [[ $previous = '--password' ]] && beep=1 # TODO: provide help about other options such as: # --old --new --with-revprop # if the previous option required a parameter, do something # or fallback on ordinary filename expansion [[ $values ]] && COMPREPLY=( $( compgen -W "$values" -- $cur ) ) [[ $dirs ]] && COMPREPLY=( $( compgen -o dirnames -- $cur ) ) [[ $exes ]] && COMPREPLY=( $( compgen -c -- $cur ) ) [[ $beep ]] && { # 'no known completion'. hummm. echo -en "\a" COMPREPLY=( '' ) } return 0 fi # provide allowed property names after property commands if [[ $isPropCmd && ( ! $prop || $stat = 'prop' ) && $cur != -* ]] then # # Ok, this part is pretty ugly. # # The issue is that ":" is a completion word separator, # which is a good idea for file:// urls but not within # property names... # # The first idea was to remove locally ":" from COMP_WORDBREAKS # and then put it back in all cases but in property name # completion. It does not always work. There is a strange bug # where one may get "svn:svn:xxx" in some unclear cases. # # Thus the handling is reprogrammed here... # The code assumes that property names look like *:*, # but it also works reasonably well with simple names. # # This hack is broken in bash4... not sure what to do about it, # especially while keeping the bash3 compatibility:-( local choices= if [[ $cur == *:* ]] then # only suggest/show possible suffixes local prefix=${cur%:*} suffix=${cur#*:} c= for c in ${allProps[@]} ; do [[ $c == $prefix:* ]] && choices="$choices ${c#*:}" done # everything will be appended to the prefix because ':' is # a separator, so cur is restricted to the suffix part. cur=$suffix else # only one choice is fine COMPREPLY=( $( compgen -W "${allProps[*]}" -- $cur ) ) [ ${#COMPREPLY[@]} -eq 1 ] && return 0 # no ':' so only suggest prefixes? local seen= n=0 last= c= for c in ${allProps[@]%:*} ; do # do not put the same prefix twice... if [[ $c == $cur* && ( ! $seen || $c != @($seen) ) ]] then let n++ last=$c choices="$choices $c:" if [[ $seen ]] then seen="$seen|$c*" else seen="$c*" fi fi done # supply two choices to force a partial completion and a beep [[ $n -eq 1 ]] && choices="$last:1 $last:2" fi COMPREPLY=( $( compgen -W "$choices" -- $cur ) ) return 0 fi # force mandatory --revprop option on revision properties if [[ $isRevProp && ! $hasRevPropOpt ]] then COMPREPLY=( $( compgen -W '--revprop' -- $cur ) ) return 0 fi # force mandatory --revision option on revision properties if [[ $isRevProp && $hasRevPropOpt && ! $hasRevisionOpt ]] then COMPREPLY=( $( compgen -W '--revision' -- $cur ) ) return 0 fi # possible completion when setting property values if [[ $isPsCmd && $prop && ( ! $val || $stat = 'val' ) ]] then # ' is a reminder for an arbitrary value local values="\' --file" case $prop in svn:keywords) # just a subset? values="Id Rev URL Date Author Header \' $SVN_BASH_KEYWORDS" ;; svn:executable|svn:needs-lock) # hmmm... canonical value * is special to the shell. values='\\*' ;; svn:eol-style) values='native LF CR CRLF' ;; svn:mime-type) # could read /etc/mime.types if available. overkill. values="text/ text/plain text/html text/xml text/rtf image/ image/png image/gif image/jpeg image/tiff audio/ audio/midi audio/mpeg video/ video/mpeg video/mp4 application/ application/octet-stream $SVN_BASH_MIME_TYPE" ;; esac COMPREPLY=( $( compgen -W "$values" -- $cur ) ) # special case for --file... return even if within an option [[ ${COMPREPLY} ]] && return 0 fi # force mandatory --accept option for 'resolve' command if [[ $cmd = 'resolve' && ! $acceptOpt ]] then COMPREPLY=( $( compgen -W '--accept' -- $cur ) ) # force option now! others will be available on later completions return 0 fi # maximum number of additional arguments expected in various forms case $cmd in merge) nExpectArgs=3 ;; mergeinfo) nExpectArgs=1 ;; copy|cp|move|mv|rename|ren|export|import) nExpectArgs=2 ;; switch|sw) [[ ! $hasRelocateOpt ]] && nExpectArgs=2 ;; help|h) nExpectArgs=0 ;; --version) nExpectArgs=0 ;; esac # the maximum number of arguments is reached for a command if [[ $nExpectArgs && $nargs -gt $nExpectArgs ]] then # some way to tell 'no completion at all'... is there a better one? # Do not say 'file completion' here. echo -en "\a" COMPREPLY=( '' ) return 0 fi # if not typing an option, # then fallback on filename expansion... if [[ $cur != -* || $stat = 'onlyarg' ]] ; then # do we allow possible expensive completion here? if [[ $SVN_BASH_COMPL_EXT == *svnstatus* ]] ; then # build status command and options # "--quiet" removes 'unknown' files local status='svn status --non-interactive' [[ $SVN_BASH_COMPL_EXT == *recurse* ]] || \ status="$status --non-recursive" # I'm not sure that it can work with externals in call cases # the output contains translatable sentences (even with quiet) [[ $SVN_BASH_COMPL_EXT == *externals* ]] || \ status="$status --ignore-externals" local cs= files= # subtlety: must not set $cur* if $cur is empty in some cases [[ $cur ]] && cs=$cur* # 'files' is set according to the current subcommand case $cmd in st*) # status completion must include all files files=$cur* ;; ci|commit|revert|di*) # anything edited files=$($status $cs| _svn_grcut '@([MADR!]*| M*|_M*)') ;; add) # unknown files files=$($status $cs| _svn_grcut '\?*') ;; unlock) # unlock locked files files=$($status $cs| _svn_grcut '@(??L*|?????[KOTB]*)') ;; resolve*) # files in conflict files=$($status $cs| _svn_grcut '@(?C*|C*)') ;; praise|blame|ann*) # any svn file but added files=$( _svn_lls all $cur* ) ;; p*) # prop commands if [[ $cmd == @($propCmds) && \ $prop == @(svn:ignore|svn:externals) ]] ; then # directory specific props files=$( _svn_lls dir . $cur* ) else # ??? added directories appear twice: foo foo/ files="$( _svn_lls all $cur* ) $($status $cs | _svn_grcut 'A*' )" fi ;; info) # information on any file files="$( _svn_lls all $cur* ) $($status $cs | _svn_grcut 'A*' )" ;; remove|rm|del*|move|mv|rename) # changing existing files files=$( _svn_lls all $cur* ) ;; mkdir) # completion in mkdir can only be for subdirs? files=$( _svn_lls dir $cur* ) ;; log|lock|up*|cl*|switch) # misc, all but added files files=$( _svn_lls all $cur* ) ;; merge) # may do a better job? URL/WCPATH files=$( _svn_lls all $cur* ) ;; ls|list) # better job? what about URLs? files=$( _svn_lls all $cur* ) ;; *) # other commands: changelist export import cat mergeinfo local fallback=1 ;; esac # when not recursive, some relevant files may exist # within subdirectories, so they are added here. # should it be restricted to svn-managed subdirs? no?? if [[ $SVN_BASH_COMPL_EXT != *recurse* ]] ; then files="$files $( _svn_lls dir $cur* )" fi # set completion depending on computed 'files' if [[ $files ]] ; then COMPREPLY=( $( compgen -W "$files" -- $cur ) ) # if empty, set to nope? [[ "${COMPREPLY[*]}" ]] || COMPREPLY=( '' ) elif [[ ! $fallback ]] ; then # this suggests no completion... echo -en "\a" COMPREPLY=( '' ) fi fi # else fallback to ordinary filename completion... return 0 fi # otherwise build possible options for the command pOpts="--username --password --no-auth-cache --non-interactive \ --trust-server-cert" mOpts="-m --message -F --file --encoding --force-log --with-revprop" rOpts="-r --revision" qOpts="-q --quiet" nOpts="-N --non-recursive --depth" gOpts="-g --use-merge-history" cOpts="--cl --changelist" cmdOpts= case $cmd in --version) cmdOpts="$qOpts" ;; add) cmdOpts="--auto-props --no-auto-props --force --targets \ --no-ignore --parents $nOpts $qOpts $pOpts" ;; blame|annotate|ann|praise) cmdOpts="$rOpts $pOpts -v --verbose --incremental --xml \ -x --extensions --force $gOpts" ;; cat) cmdOpts="$rOpts $pOpts" ;; changelist|cl) cmdOpts="--targets $pOpts $qOpts $cOpts \ -R --recursive --depth --remove" ;; checkout|co) cmdOpts="$rOpts $qOpts $nOpts $pOpts --ignore-externals \ --force" ;; cleanup) cmdOpts="--diff3-cmd $pOpts" ;; commit|ci) cmdOpts="$mOpts $qOpts $nOpts --targets --editor-cmd $pOpts \ --no-unlock $cOpts --keep-changelists" ;; copy|cp) cmdOpts="$mOpts $rOpts $qOpts --editor-cmd $pOpts --parents \ --ignore-externals" ;; delete|del|remove|rm) cmdOpts="--force $mOpts $qOpts --targets --editor-cmd $pOpts \ --keep-local" ;; diff|di) cmdOpts="$rOpts -x --extensions --diff-cmd --no-diff-deleted \ $nOpts $pOpts --force --old --new --notice-ancestry \ -c --change --summarize $cOpts --xml --git \ --internal-diff --show-copies-as-adds" ;; export) cmdOpts="$rOpts $qOpts $pOpts $nOpts --force --native-eol \ --ignore-externals --ignore-keywords" ;; help|h|\?) cmdOpts= ;; import) cmdOpts="--auto-props --no-auto-props $mOpts $qOpts $nOpts \ --no-ignore --editor-cmd $pOpts --force" ;; info) cmdOpts="$pOpts $rOpts --targets -R --recursive --depth \ --incremental --xml $cOpts" ;; list|ls) cmdOpts="$rOpts -v --verbose -R --recursive $pOpts \ --incremental --xml --depth" ;; lock) cmdOpts="-m --message -F --file --encoding --force-log \ --targets --force $pOpts" ;; log) cmdOpts="$rOpts -v --verbose --targets $pOpts --stop-on-copy \ --incremental --xml $qOpts -l --limit -c --change \ $gOpts --with-all-revprops --with-revprop --depth \ --diff --diff-cmd -x --extensions --internal-diff \ --with-no-revprops" ;; merge) cmdOpts="$rOpts $nOpts $qOpts --force --dry-run --diff3-cmd \ $pOpts --ignore-ancestry -c --change -x --extensions \ --record-only --accept --reintegrate \ --allow-mixed-revisions" ;; mergeinfo) cmdOpts="$rOpts $pOpts --depth --show-revs -R --recursive" ;; mkdir) cmdOpts="$mOpts $qOpts --editor-cmd $pOpts --parents" ;; move|mv|rename|ren) cmdOpts="$mOpts $rOpts $qOpts --force --editor-cmd $pOpts \ --parents" ;; patch) cmdOpts="$qOpts $pOpts --dry-run --ignore-whitespace --reverse-diff --strip" ;; propdel|pdel|pd) cmdOpts="$qOpts -R --recursive $rOpts $pOpts $cOpts \ --depth" [[ $isRevProp || ! $prop ]] && cmdOpts="$cmdOpts --revprop" ;; propedit|pedit|pe) cmdOpts="--editor-cmd $pOpts $mOpts --force" [[ $isRevProp || ! $prop ]] && \ cmdOpts="$cmdOpts --revprop $rOpts" ;; propget|pget|pg) cmdOpts="-v --verbose -R --recursive $rOpts --strict $pOpts $cOpts \ --depth --xml" [[ $isRevProp || ! $prop ]] && cmdOpts="$cmdOpts --revprop" ;; proplist|plist|pl) cmdOpts="-v --verbose -R --recursive $rOpts --revprop $qOpts \ $pOpts $cOpts --depth --xml" ;; propset|pset|ps) cmdOpts="$qOpts --targets -R --recursive \ --encoding $pOpts --force $cOpts --depth" [[ $isRevProp || ! $prop ]] && \ cmdOpts="$cmdOpts --revprop $rOpts" [[ $val ]] || cmdOpts="$cmdOpts -F --file" ;; relocate) cmdOpts="--ignore-externals $pOpts" ;; resolve) cmdOpts="--targets -R --recursive $qOpts $pOpts --accept \ --depth" ;; resolved) cmdOpts="--targets -R --recursive $qOpts $pOpts --depth" ;; revert) cmdOpts="--targets -R --recursive $qOpts $cOpts \ --depth $pOpts" ;; status|stat|st) cmdOpts="-u --show-updates -v --verbose $nOpts $qOpts $pOpts \ --no-ignore --ignore-externals --incremental --xml \ $cOpts" ;; switch|sw) cmdOpts="--relocate $rOpts $nOpts $qOpts $pOpts --diff3-cmd \ --force --accept --ignore-externals --set-depth \ --ignore-ancestry" ;; unlock) cmdOpts="--targets --force $pOpts" ;; update|up) cmdOpts="$rOpts $nOpts $qOpts $pOpts --diff3-cmd \ --ignore-externals --force --accept $cOpts \ --parents --editor-cmd --set-depth" ;; upgrade) cmdOpts="$qOpts $pOpts" ;; *) ;; esac # add options that are nearly always available [[ "$cmd" != "--version" ]] && cmdOpts="$cmdOpts $helpOpts" cmdOpts="$cmdOpts --config-dir --config-option" # --accept (edit|launch) incompatible with --non-interactive if [[ $acceptOpt == @(edit|launch) ]] ; then cmdOpts=${cmdOpts/ --non-interactive / } fi # take out options already given for opt in $options do local optBase # remove leading dashes and arguments case $opt in --*) optBase=${opt/=*/} ;; -*) optBase=${opt:0:2} ;; esac cmdOpts=" $cmdOpts " cmdOpts=${cmdOpts/ ${optBase} / } # take out alternatives and mutually exclusives case $optBase in -v) cmdOpts=${cmdOpts/ --verbose / } ;; --verbose) cmdOpts=${cmdOpts/ -v / } ;; -N) cmdOpts=${cmdOpts/ --non-recursive / } ;; --non-recursive) cmdOpts=${cmdOpts/ -N / } ;; -R) cmdOpts=${cmdOpts/ --recursive / } ;; --recursive) cmdOpts=${cmdOpts/ -R / } ;; -x) cmdOpts=${cmdOpts/ --extensions / } ;; --extensions) cmdOpts=${cmdOpts/ -x / } ;; -q) cmdOpts=${cmdOpts/ --quiet / } ;; --quiet) cmdOpts=${cmdOpts/ -q / } ;; -h) cmdOpts=${cmdOpts/ --help / } ;; --help) cmdOpts=${cmdOpts/ -h / } ;; -l) cmdOpts=${cmdOpts/ --limit / } ;; --limit) cmdOpts=${cmdOpts/ -l / } ;; -r) cmdOpts=${cmdOpts/ --revision / } ;; --revision) cmdOpts=${cmdOpts/ -r / } ;; -c) cmdOpts=${cmdOpts/ --change / } ;; --change) cmdOpts=${cmdOpts/ -c / } ;; --auto-props) cmdOpts=${cmdOpts/ --no-auto-props / } ;; --no-auto-props) cmdOpts=${cmdOpts/ --auto-props / } ;; -g) cmdOpts=${cmdOpts/ --use-merge-history / } ;; --use-merge-history) cmdOpts=${cmdOpts/ -g / } ;; -m|--message|-F|--file) cmdOpts=${cmdOpts/ --message / } cmdOpts=${cmdOpts/ -m / } cmdOpts=${cmdOpts/ --file / } cmdOpts=${cmdOpts/ -F / } ;; esac # remove help options within help subcommand if [ $isHelpCmd ] ; then cmdOpts=${cmdOpts/ -h / } cmdOpts=${cmdOpts/ --help / } fi done # provide help about available options COMPREPLY=( $( compgen -W "$cmdOpts" -- $cur ) ) return 0 } complete -F _svn -o default -X '@(*/.svn|*/.svn/|.svn|.svn/)' svn _svnadmin () { local cur cmds cmdOpts optsParam opt helpCmds optBase i COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} # Possible expansions, without pure-prefix abbreviations such as "h". cmds='crashtest create deltify dump help hotcopy list-dblogs \ list-unused-dblogs load lslocks lstxns pack recover rmlocks \ rmtxns setlog setrevprop setuuid upgrade verify --version' if [[ $COMP_CWORD -eq 1 ]] ; then COMPREPLY=( $( compgen -W "$cmds" -- $cur ) ) return 0 fi # options that require a parameter # note: continued lines must end '|' continuing lines must start '|' optsParam="-r|--revision|--parent-dir|--fs-type" # if not typing an option, or if the previous option required a # parameter, then fallback on ordinary filename expansion helpCmds='help|--help|h|\?' if [[ ${COMP_WORDS[1]} != @($helpCmds) ]] && \ [[ "$cur" != -* ]] || \ [[ ${COMP_WORDS[COMP_CWORD-1]} == @($optsParam) ]] ; then return 0 fi cmdOpts= case ${COMP_WORDS[1]} in create) cmdOpts="--bdb-txn-nosync --bdb-log-keep --config-dir \ --fs-type --pre-1.4-compatible --pre-1.5-compatible" ;; deltify) cmdOpts="-r --revision -q --quiet" ;; dump) cmdOpts="-r --revision --incremental -q --quiet --deltas" ;; help|h|\?) cmdOpts="$cmds" ;; hotcopy) cmdOpts="--clean-logs" ;; load) cmdOpts="--ignore-uuid --force-uuid --parent-dir -q --quiet \ --use-pre-commit-hook --use-post-commit-hook" ;; recover) cmdOpts="--wait" ;; rmtxns) cmdOpts="-q --quiet" ;; setlog) cmdOpts="-r --revision --bypass-hooks" ;; setrevprop) cmdOpts="-r --revision --use-pre-revprop-change-hook \ --use-post-revprop-change-hook" ;; verify) cmdOpts="-r --revision -q --quiet" ;; *) ;; esac cmdOpts="$cmdOpts --help -h" # take out options already given for (( i=2; i<=$COMP_CWORD-1; ++i )) ; do opt=${COMP_WORDS[$i]} case $opt in --*) optBase=${opt/=*/} ;; -*) optBase=${opt:0:2} ;; esac cmdOpts=" $cmdOpts " cmdOpts=${cmdOpts/ ${optBase} / } # take out alternatives case $optBase in -q) cmdOpts=${cmdOpts/ --quiet / } ;; --quiet) cmdOpts=${cmdOpts/ -q / } ;; -h) cmdOpts=${cmdOpts/ --help / } ;; --help) cmdOpts=${cmdOpts/ -h / } ;; -r) cmdOpts=${cmdOpts/ --revision / } ;; --revision) cmdOpts=${cmdOpts/ -r / } ;; esac # skip next option if this one requires a parameter if [[ $opt == @($optsParam) ]] ; then ((++i)) fi done COMPREPLY=( $( compgen -W "$cmdOpts" -- $cur ) ) return 0 } complete -F _svnadmin -o default svnadmin _svndumpfilter () { local cur cmds cmdOpts optsParam opt helpCmds optBase i COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} # Possible expansions, without pure-prefix abbreviations such as "h". cmds='exclude help include --version' if [[ $COMP_CWORD -eq 1 ]] ; then COMPREPLY=( $( compgen -W "$cmds" -- $cur ) ) return 0 fi # options that require a parameter # note: continued lines must end '|' continuing lines must start '|' optsParam="--targets" # if not typing an option, or if the previous option required a # parameter, then fallback on ordinary filename expansion helpCmds='help|--help|h|\?' if [[ ${COMP_WORDS[1]} != @($helpCmds) ]] && \ [[ "$cur" != -* ]] || \ [[ ${COMP_WORDS[COMP_CWORD-1]} == @($optsParam) ]] ; then return 0 fi cmdOpts= case ${COMP_WORDS[1]} in exclude|include) cmdOpts="--drop-empty-revs --renumber-revs --skip-missing-merge-sources --targets --preserve-revprops --quiet" ;; help|h|\?) cmdOpts="$cmds" ;; *) ;; esac cmdOpts="$cmdOpts --help -h" # take out options already given for (( i=2; i<=$COMP_CWORD-1; ++i )) ; do opt=${COMP_WORDS[$i]} case $opt in --*) optBase=${opt/=*/} ;; -*) optBase=${opt:0:2} ;; esac cmdOpts=" $cmdOpts " cmdOpts=${cmdOpts/ ${optBase} / } # take out alternatives case $optBase in -h) cmdOpts=${cmdOpts/ --help / } ;; --help) cmdOpts=${cmdOpts/ -h / } ;; esac # skip next option if this one requires a parameter if [[ $opt == @($optsParam) ]] ; then ((++i)) fi done COMPREPLY=( $( compgen -W "$cmdOpts" -- $cur ) ) return 0 } complete -F _svndumpfilter -o default svndumpfilter _svnlook () { local cur cmds cmdOpts optsParam opt helpCmds optBase i COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} # Possible expansions, without pure-prefix abbreviations such as "h". cmds='author cat changed date diff dirs-changed help history info \ lock log propget proplist tree uuid youngest --version' if [[ $COMP_CWORD -eq 1 ]] ; then COMPREPLY=( $( compgen -W "$cmds" -- $cur ) ) return 0 fi # options that require a parameter # note: continued lines must end '|' continuing lines must start '|' optsParam="-r|--revision|-t|--transaction|-l|--limit|-x|--extensions" # if not typing an option, or if the previous option required a # parameter, then fallback on ordinary filename expansion helpCmds='help|--help|h|\?' if [[ ${COMP_WORDS[1]} != @($helpCmds) ]] && \ [[ "$cur" != -* ]] || \ [[ ${COMP_WORDS[COMP_CWORD-1]} == @($optsParam) ]] ; then return 0 fi cmdOpts= case ${COMP_WORDS[1]} in author) cmdOpts="-r --revision -t --transaction" ;; cat) cmdOpts="-r --revision -t --transaction" ;; changed) cmdOpts="-r --revision -t --transaction --copy-info" ;; date) cmdOpts="-r --revision -t --transaction" ;; diff) cmdOpts="-r --revision -t --transaction --diff-copy-from \ --no-diff-added --no-diff-deleted -x --extensions" ;; dirs-changed) cmdOpts="-r --revision -t --transaction" ;; help|h|\?) cmdOpts="$cmds" ;; history) cmdOpts="-r --revision -l --limit --show-ids" ;; info) cmdOpts="-r --revision -t --transaction" ;; lock) cmdOpts= ;; log) cmdOpts="-r --revision -t --transaction" ;; propget|pget|pg) cmdOpts="-r --revision -t --transaction --revprop" ;; proplist|plist|pl) cmdOpts="-r --revision -t --transaction --revprop -v --verbose --xml" ;; tree) cmdOpts="-r --revision -t --transaction --full-paths -N --non-recursive --show-ids" ;; uuid) cmdOpts= ;; youngest) cmdOpts= ;; *) ;; esac cmdOpts="$cmdOpts --help -h" # take out options already given for (( i=2; i<=$COMP_CWORD-1; ++i )) ; do opt=${COMP_WORDS[$i]} case $opt in --*) optBase=${opt/=*/} ;; -*) optBase=${opt:0:2} ;; esac cmdOpts=" $cmdOpts " cmdOpts=${cmdOpts/ ${optBase} / } # take out alternatives case $optBase in -N) cmdOpts=${cmdOpts/ --non-recursive / } ;; --non-recursive) cmdOpts=${cmdOpts/ -N / } ;; -h) cmdOpts=${cmdOpts/ --help / } ;; --help) cmdOpts=${cmdOpts/ -h / } ;; -l) cmdOpts=${cmdOpts/ --limit / } ;; --limit) cmdOpts=${cmdOpts/ -l / } ;; -r) cmdOpts=${cmdOpts/ --revision / } ;; --revision) cmdOpts=${cmdOpts/ -r / } ;; -t) cmdOpts=${cmdOpts/ --transaction / } ;; --transaction) cmdOpts=${cmdOpts/ -t / } ;; -v) cmdOpts=${cmdOpts/ --verbose / } ;; --verbose) cmdOpts=${cmdOpts/ -v / } ;; -x) cmdOpts=${cmdOpts/ --extensions / } ;; --extensions) cmdOpts=${cmdOpts/ -x / } ;; esac # skip next option if this one requires a parameter if [[ $opt == @($optsParam) ]] ; then ((++i)) fi done COMPREPLY=( $( compgen -W "$cmdOpts" -- $cur ) ) return 0 } complete -F _svnlook -o default svnlook _svnsync () { local cur cmds cmdOpts optsParam opt helpCmds optBase i COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} # Possible expansions, without pure-prefix abbreviations such as "h". cmds='copy-revprops help info initialize synchronize --version' if [[ $COMP_CWORD -eq 1 ]] ; then COMPREPLY=( $( compgen -W "$cmds" -- $cur ) ) return 0 fi # options that require a parameter # note: continued lines must end '|' continuing lines must start '|' optsParam="--config-dir|--config-option|--source-username|--source-password" optsParam="$optsParam|--sync-username|--sync-password" # if not typing an option, or if the previous option required a # parameter, then fallback on ordinary filename expansion helpCmds='help|--help|h|\?' if [[ ${COMP_WORDS[1]} != @($helpCmds) ]] && \ [[ "$cur" != -* ]] || \ [[ ${COMP_WORDS[COMP_CWORD-1]} == @($optsParam) ]] ; then return 0 fi cmdOpts= case ${COMP_WORDS[1]} in copy-revprops|initialize|init|synchronize|sync) cmdOpts="--non-interactive --no-auth-cache --trust-server-cert \ --source-username --source-password --sync-username \ --sync-password --config-dir --config-option -q --quiet" ;; help|h|\?) cmdOpts="$cmds" ;; info) cmdOpts="--non-interactive --no-auth-cache --trust-server-cert \ --source-username --source-password --sync-username \ --sync-password --config-dir --config-option" ;; *) ;; esac cmdOpts="$cmdOpts --help -h" # take out options already given for (( i=2; i<=$COMP_CWORD-1; ++i )) ; do opt=${COMP_WORDS[$i]} case $opt in --*) optBase=${opt/=*/} ;; -*) optBase=${opt:0:2} ;; esac cmdOpts=" $cmdOpts " cmdOpts=${cmdOpts/ ${optBase} / } # take out alternatives case $optBase in -h) cmdOpts=${cmdOpts/ --help / } ;; --help) cmdOpts=${cmdOpts/ -h / } ;; -q) cmdOpts=${cmdOpts/ --quiet / } ;; --quiet) cmdOpts=${cmdOpts/ -q / } ;; esac # skip next option if this one requires a parameter if [[ $opt == @($optsParam) ]] ; then ((++i)) fi done COMPREPLY=( $( compgen -W "$cmdOpts" -- $cur ) ) return 0 } complete -F _svnsync -o default svnsync # reasonable completion for 'svnversion' _svnversion () { local cmdOpts=" -n --no-newline -c --committed -h --help --version " local cur=${COMP_WORDS[COMP_CWORD]} COMPREPLY=() # parse current options local options= wcpath= trailurl= last='none' stat= opt= i=-1 isCur= for opt in ${COMP_WORDS[@]} do [[ $i -eq $COMP_CWORD ]] && stat=$last let i++ # are we processing the current word? isCur= [[ $i -eq $COMP_CWORD ]] && isCur=1 # skip first command, should be 'svnversion' if [ $last = 'none' ] ; then last='first' continue fi # get options if [[ $last != 'arg' && $opt == -* ]] then # if '--' is at the current position, it means that we are looking # for '--*' options, and not the end of option processing. if [[ $opt = '--' && ! $isCur ]] then last='arg' else options="$options $opt " last='opt' fi continue fi # get arguments if [[ $opt != -* ]] then last='arg' if [[ ! $wcpath ]] then wcpath=$opt elif [[ ! $trailurl ]] then trailurl=$opt fi fi done [[ $stat ]] || stat=$last # argument part if [[ $cur != -* || $stat = 'arg' ]] then [[ $wcpath && $trailurl ]] && COMPREPLY=( '' ) return 0 fi # suggest options, and take out already given options for opt in $options do # take out options cmdOpts=${cmdOpts/ $opt / } # take out alternatives case $opt in -n) cmdOpts=${cmdOpts/ --no-newline / } ;; --no-newline) cmdOpts=${cmdOpts/ -n / } ;; -h) cmdOpts=${cmdOpts/ --help / } ;; --help) cmdOpts=${cmdOpts/ -h / } ;; -c) cmdOpts=${cmdOpts/ --committed / } ;; --committed) cmdOpts=${cmdOpts/ -c / } ;; esac done COMPREPLY=( $( compgen -W "$cmdOpts" -- $cur ) ) return 0 } # -X option does not seem to work? complete -F _svnversion -o dirnames -X '*.svn*' svnversion