PNG  IHDRQgAMA a cHRMz&u0`:pQ<bKGDgmIDATxwUﹻ& ^CX(J I@ "% (** BX +*i"]j(IH{~R)[~>h{}gy)I$Ij .I$I$ʊy@}x.: $I$Ii}VZPC)I$IF ^0ʐJ$I$Q^}{"r=OzI$gRZeC.IOvH eKX $IMpxsk.쒷/&r[޳<v| .I~)@$updYRa$I |M.e JaֶpSYR6j>h%IRز if&uJ)M$I vLi=H;7UJ,],X$I1AҒJ$ XY XzI@GNҥRT)E@;]K*Mw;#5_wOn~\ DC&$(A5 RRFkvIR}l!RytRl;~^ǷJj اy뷦BZJr&ӥ8Pjw~vnv X^(I;4R=P[3]J,]ȏ~:3?[ a&e)`e*P[4]T=Cq6R[ ~ޤrXR Հg(t_HZ-Hg M$ãmL5R uk*`%C-E6/%[t X.{8P9Z.vkXŐKjgKZHg(aK9ڦmKjѺm_ \#$5,)-  61eJ,5m| r'= &ڡd%-]J on Xm|{ RҞe $eڧY XYrԮ-a7RK6h>n$5AVڴi*ֆK)mѦtmr1p| q:흺,)Oi*ֺK)ܬ֦K-5r3>0ԔHjJئEZj,%re~/z%jVMڸmrt)3]J,T K֦OvԒgii*bKiNO~%PW0=dii2tJ9Jݕ{7"I P9JKTbu,%r"6RKU}Ij2HKZXJ,妝 XYrP ެ24c%i^IK|.H,%rb:XRl1X4Pe/`x&P8Pj28Mzsx2r\zRPz4J}yP[g=L) .Q[6RjWgp FIH*-`IMRaK9TXcq*I y[jE>cw%gLRԕiFCj-ďa`#e~I j,%r,)?[gp FI˨mnWX#>mʔ XA DZf9,nKҲzIZXJ,L#kiPz4JZF,I,`61%2s $,VOϚ2/UFJfy7K> X+6 STXIeJILzMfKm LRaK9%|4p9LwJI!`NsiazĔ)%- XMq>pk$-$Q2x#N ؎-QR}ᶦHZډ)J,l#i@yn3LN`;nڔ XuX5pF)m|^0(>BHF9(cզEerJI rg7 4I@z0\JIi䵙RR0s;$s6eJ,`n 䂦0a)S)A 1eJ,堌#635RIgpNHuTH_SԕqVe ` &S)>p;S$魁eKIuX`I4춒o}`m$1":PI<[v9^\pTJjriRŭ P{#{R2,`)e-`mgj~1ϣLKam7&U\j/3mJ,`F;M'䱀 .KR#)yhTq;pcK9(q!w?uRR,n.yw*UXj#\]ɱ(qv2=RqfB#iJmmL<]Y͙#$5 uTU7ӦXR+q,`I}qL'`6Kͷ6r,]0S$- [RKR3oiRE|nӦXR.(i:LDLTJjY%o:)6rxzҒqTJjh㞦I.$YR.ʼnGZ\ֿf:%55 I˼!6dKxm4E"mG_ s? .e*?LRfK9%q#uh$)i3ULRfK9yxm܌bj84$i1U^@Wbm4uJ,ҪA>_Ij?1v32[gLRD96oTaR׿N7%L2 NT,`)7&ƝL*꽙yp_$M2#AS,`)7$rkTA29_Iye"|/0t)$n XT2`YJ;6Jx".e<`$) PI$5V4]29SRI>~=@j]lp2`K9Jaai^" Ԋ29ORI%:XV5]JmN9]H;1UC39NI%Xe78t)a;Oi Ҙ>Xt"~G>_mn:%|~ޅ_+]$o)@ǀ{hgN;IK6G&rp)T2i୦KJuv*T=TOSV>(~D>dm,I*Ɛ:R#ۙNI%D>G.n$o;+#RR!.eU˽TRI28t)1LWϚ>IJa3oFbu&:tJ*(F7y0ZR ^p'Ii L24x| XRI%ۄ>S1]Jy[zL$adB7.eh4%%누>WETf+3IR:I3Xה)3אOۦSRO'ٺ)S}"qOr[B7ϙ.edG)^ETR"RtRݜh0}LFVӦDB^k_JDj\=LS(Iv─aTeZ%eUAM-0;~˃@i|l @S4y72>sX-vA}ϛBI!ݎߨWl*)3{'Y|iSlEڻ(5KtSI$Uv02,~ԩ~x;P4ցCrO%tyn425:KMlD ^4JRxSهF_}شJTS6uj+ﷸk$eZO%G*^V2u3EMj3k%)okI]dT)URKDS 7~m@TJR~荪fT"֛L \sM -0T KfJz+nإKr L&j()[E&I ߴ>e FW_kJR|!O:5/2跌3T-'|zX ryp0JS ~^F>-2< `*%ZFP)bSn"L :)+pʷf(pO3TMW$~>@~ū:TAIsV1}S2<%ޟM?@iT ,Eūoz%i~g|`wS(]oȤ8)$ ntu`өe`6yPl IzMI{ʣzʨ )IZ2= ld:5+請M$-ї;U>_gsY$ÁN5WzWfIZ)-yuXIfp~S*IZdt;t>KūKR|$#LcԀ+2\;kJ`]YǔM1B)UbG"IRߊ<xܾӔJ0Z='Y嵤 Leveg)$znV-º^3Ւof#0Tfk^Zs[*I꯳3{)ˬW4Ւ4 OdpbZRS|*I 55#"&-IvT&/윚Ye:i$ 9{LkuRe[I~_\ؠ%>GL$iY8 9ܕ"S`kS.IlC;Ҏ4x&>u_0JLr<J2(^$5L s=MgV ~,Iju> 7r2)^=G$1:3G< `J3~&IR% 6Tx/rIj3O< ʔ&#f_yXJiގNSz; Tx(i8%#4 ~AS+IjerIUrIj362v885+IjAhK__5X%nV%Iͳ-y|7XV2v4fzo_68"S/I-qbf; LkF)KSM$ Ms>K WNV}^`-큧32ŒVؙGdu,^^m%6~Nn&͓3ŒVZMsRpfEW%IwdǀLm[7W&bIRL@Q|)* i ImsIMmKmyV`i$G+R 0tV'!V)֏28vU7͒vHꦼtxꗞT ;S}7Mf+fIRHNZUkUx5SAJㄌ9MqμAIRi|j5)o*^'<$TwI1hEU^c_j?Е$%d`z cyf,XO IJnTgA UXRD }{H}^S,P5V2\Xx`pZ|Yk:$e ~ @nWL.j+ϝYb퇪bZ BVu)u/IJ_ 1[p.p60bC >|X91P:N\!5qUB}5a5ja `ubcVxYt1N0Zzl4]7­gKj]?4ϻ *[bg$)+À*x쳀ogO$~,5 زUS9 lq3+5mgw@np1sso Ӻ=|N6 /g(Wv7U;zωM=wk,0uTg_`_P`uz?2yI!b`kĸSo+Qx%!\οe|އԁKS-s6pu_(ֿ$i++T8=eY; צP+phxWQv*|p1. ά. XRkIQYP,drZ | B%wP|S5`~́@i޾ E;Չaw{o'Q?%iL{u D?N1BD!owPHReFZ* k_-~{E9b-~P`fE{AܶBJAFO wx6Rox5 K5=WwehS8 (JClJ~ p+Fi;ŗo+:bD#g(C"wA^ r.F8L;dzdIHUX݆ϞXg )IFqem%I4dj&ppT{'{HOx( Rk6^C٫O.)3:s(۳(Z?~ٻ89zmT"PLtw䥈5&b<8GZ-Y&K?e8,`I6e(֍xb83 `rzXj)F=l($Ij 2*(F?h(/9ik:I`m#p3MgLaKjc/U#n5S# m(^)=y=đx8ŬI[U]~SцA4p$-F i(R,7Cx;X=cI>{Km\ o(Tv2vx2qiiDJN,Ҏ!1f 5quBj1!8 rDFd(!WQl,gSkL1Bxg''՞^ǘ;pQ P(c_ IRujg(Wz bs#P­rz> k c&nB=q+ؔXn#r5)co*Ũ+G?7< |PQӣ'G`uOd>%Mctz# Ԫڞ&7CaQ~N'-P.W`Oedp03C!IZcIAMPUۀ5J<\u~+{9(FbbyAeBhOSܳ1 bÈT#ŠyDžs,`5}DC-`̞%r&ڙa87QWWp6e7 Rϫ/oY ꇅ Nܶըtc!LA T7V4Jsū I-0Pxz7QNF_iZgúWkG83 0eWr9 X]㾮݁#Jˢ C}0=3ݱtBi]_ &{{[/o[~ \q鯜00٩|cD3=4B_b RYb$óBRsf&lLX#M*C_L܄:gx)WΘsGSbuL rF$9';\4Ɍq'n[%p.Q`u hNb`eCQyQ|l_C>Lb꟟3hSb #xNxSs^ 88|Mz)}:](vbۢamŖ࿥ 0)Q7@0=?^k(*J}3ibkFn HjB׻NO z x}7p 0tfDX.lwgȔhԾŲ }6g E |LkLZteu+=q\Iv0쮑)QٵpH8/2?Σo>Jvppho~f>%bMM}\//":PTc(v9v!gոQ )UfVG+! 35{=x\2+ki,y$~A1iC6#)vC5^>+gǵ@1Hy٪7u;p psϰu/S <aʸGu'tD1ԝI<pg|6j'p:tպhX{o(7v],*}6a_ wXRk,O]Lܳ~Vo45rp"N5k;m{rZbΦ${#)`(Ŵg,;j%6j.pyYT?}-kBDc3qA`NWQū20/^AZW%NQ MI.X#P#,^Ebc&?XR tAV|Y.1!؅⨉ccww>ivl(JT~ u`ٵDm q)+Ri x/x8cyFO!/*!/&,7<.N,YDŽ&ܑQF1Bz)FPʛ?5d 6`kQձ λc؎%582Y&nD_$Je4>a?! ͨ|ȎWZSsv8 j(I&yj Jb5m?HWp=g}G3#|I,5v珿] H~R3@B[☉9Ox~oMy=J;xUVoj bUsl_35t-(ՃɼRB7U!qc+x4H_Qo֮$[GO<4`&č\GOc[.[*Af%mG/ ňM/r W/Nw~B1U3J?P&Y )`ѓZ1p]^l“W#)lWZilUQu`-m|xĐ,_ƪ|9i:_{*(3Gѧ}UoD+>m_?VPۅ15&}2|/pIOʵ> GZ9cmíتmnz)yߐbD >e}:) r|@R5qVSA10C%E_'^8cR7O;6[eKePGϦX7jb}OTGO^jn*媓7nGMC t,k31Rb (vyܴʭ!iTh8~ZYZp(qsRL ?b}cŨʊGO^!rPJO15MJ[c&~Z`"ѓޔH1C&^|Ш|rʼ,AwĴ?b5)tLU)F| &g٣O]oqSUjy(x<Ϳ3 .FSkoYg2 \_#wj{u'rQ>o;%n|F*O_L"e9umDds?.fuuQbIWz |4\0 sb;OvxOSs; G%T4gFRurj(֍ڑb uԖKDu1MK{1^ q; C=6\8FR艇!%\YÔU| 88m)֓NcLve C6z;o&X x59:q61Z(T7>C?gcļxѐ Z oo-08jہ x,`' ҔOcRlf~`jj".Nv+sM_]Zk g( UOPyεx%pUh2(@il0ݽQXxppx-NS( WO+轾 nFߢ3M<;z)FBZjciu/QoF 7R¥ ZFLF~#ȣߨ^<쩡ݛкvџ))ME>ώx4m#!-m!L;vv#~Y[đKmx9.[,UFS CVkZ +ߟrY٧IZd/ioi$%͝ب_ֶX3ܫhNU ZZgk=]=bbJS[wjU()*I =ώ:}-蹞lUj:1}MWm=̛ _ ¾,8{__m{_PVK^n3esw5ӫh#$-q=A̟> ,^I}P^J$qY~Q[ Xq9{#&T.^GVj__RKpn,b=`żY@^՝;z{paVKkQXj/)y TIc&F;FBG7wg ZZDG!x r_tƢ!}i/V=M/#nB8 XxЫ ^@CR<{䤭YCN)eKOSƟa $&g[i3.C6xrOc8TI;o hH6P&L{@q6[ Gzp^71j(l`J}]e6X☉#͕ ׈$AB1Vjh㭦IRsqFBjwQ_7Xk>y"N=MB0 ,C #o6MRc0|$)ف"1!ixY<B9mx `,tA>)5ػQ?jQ?cn>YZe Tisvh# GMމȇp:ԴVuږ8ɼH]C.5C!UV;F`mbBk LTMvPʍϤj?ԯ/Qr1NB`9s"s TYsz &9S%U԰> {<ؿSMxB|H\3@!U| k']$U+> |HHMLޢ?V9iD!-@x TIî%6Z*9X@HMW#?nN ,oe6?tQwڱ.]-y':mW0#!J82qFjH -`ѓ&M0u Uγmxϵ^-_\])@0Rt.8/?ٰCY]x}=sD3ojަЫNuS%U}ԤwHH>ڗjܷ_3gN q7[q2la*ArǓԖ+p8/RGM ]jacd(JhWko6ڎbj]i5Bj3+3!\j1UZLsLTv8HHmup<>gKMJj0@H%,W΃7R) ">c, xixј^ aܖ>H[i.UIHc U1=yW\=S*GR~)AF=`&2h`DzT󑓶J+?W+}C%P:|0H܆}-<;OC[~o.$~i}~HQ TvXΈr=b}$vizL4:ȰT|4~*!oXQR6Lk+#t/g lԁߖ[Jڶ_N$k*". xsxX7jRVbAAʯKҎU3)zSNN _'s?f)6X!%ssAkʱ>qƷb hg %n ~p1REGMHH=BJiy[<5 ǁJҖgKR*倳e~HUy)Ag,K)`Vw6bRR:qL#\rclK/$sh*$ 6덤 KԖc 3Z9=Ɣ=o>X Ώ"1 )a`SJJ6k(<c e{%kϊP+SL'TcMJWRm ŏ"w)qc ef꒵i?b7b('"2r%~HUS1\<(`1Wx9=8HY9m:X18bgD1u ~|H;K-Uep,, C1 RV.MR5άh,tWO8WC$ XRVsQS]3GJ|12 [vM :k#~tH30Rf-HYݺ-`I9%lIDTm\ S{]9gOڒMNCV\G*2JRŨ;Rҏ^ڽ̱mq1Eu?To3I)y^#jJw^Ńj^vvlB_⋌P4x>0$c>K†Aļ9s_VjTt0l#m>E-,,x,-W)سo&96RE XR.6bXw+)GAEvL)͞K4$p=Ũi_ѱOjb HY/+@θH9޼]Nԥ%n{ &zjT? Ty) s^ULlb,PiTf^<À] 62R^V7)S!nllS6~͝V}-=%* ʻ>G DnK<y&>LPy7'r=Hj 9V`[c"*^8HpcO8bnU`4JȪAƋ#1_\ XϘHPRgik(~G~0DAA_2p|J묭a2\NCr]M_0 ^T%e#vD^%xy-n}-E\3aS%yN!r_{ )sAw ڼp1pEAk~v<:`'ӭ^5 ArXOI驻T (dk)_\ PuA*BY]yB"l\ey hH*tbK)3 IKZ򹞋XjN n *n>k]X_d!ryBH ]*R 0(#'7 %es9??ښFC,ՁQPjARJ\Ρw K#jahgw;2$l*) %Xq5!U᢯6Re] |0[__64ch&_}iL8KEgҎ7 M/\`|.p,~`a=BR?xܐrQ8K XR2M8f ?`sgWS%" Ԉ 7R%$ N}?QL1|-эټwIZ%pvL3Hk>,ImgW7{E xPHx73RA @RS CC !\ȟ5IXR^ZxHл$Q[ŝ40 (>+ _C >BRt<,TrT {O/H+˟Pl6 I B)/VC<6a2~(XwV4gnXR ϱ5ǀHٻ?tw똤Eyxp{#WK qG%5],(0ӈH HZ])ג=K1j&G(FbM@)%I` XRg ʔ KZG(vP,<`[ Kn^ SJRsAʠ5xՅF`0&RbV tx:EaUE/{fi2;.IAwW8/tTxAGOoN?G}l L(n`Zv?pB8K_gI+ܗ #i?ޙ.) p$utc ~DžfՈEo3l/)I-U?aԅ^jxArA ΧX}DmZ@QLےbTXGd.^|xKHR{|ΕW_h] IJ`[G9{).y) 0X YA1]qp?p_k+J*Y@HI>^?gt.06Rn ,` ?);p pSF9ZXLBJPWjgQ|&)7! HjQt<| ؅W5 x W HIzYoVMGP Hjn`+\(dNW)F+IrS[|/a`K|ͻ0Hj{R,Q=\ (F}\WR)AgSG`IsnAR=|8$}G(vC$)s FBJ?]_u XRvύ6z ŨG[36-T9HzpW̞ú Xg큽=7CufzI$)ki^qk-) 0H*N` QZkk]/tnnsI^Gu't=7$ Z;{8^jB% IItRQS7[ϭ3 $_OQJ`7!]W"W,)Iy W AJA;KWG`IY{8k$I$^%9.^(`N|LJ%@$I}ֽp=FB*xN=gI?Q{٥4B)mw $Igc~dZ@G9K X?7)aK%݅K$IZ-`IpC U6$I\0>!9k} Xa IIS0H$I H ?1R.Чj:4~Rw@p$IrA*u}WjWFPJ$I➓/6#! LӾ+ X36x8J |+L;v$Io4301R20M I$-E}@,pS^ޟR[/s¹'0H$IKyfŸfVOπFT*a$I>He~VY/3R/)>d$I>28`Cjw,n@FU*9ttf$I~<;=/4RD~@ X-ѕzἱI$: ԍR a@b X{+Qxuq$IЛzo /~3\8ڒ4BN7$IҀj V]n18H$IYFBj3̵̚ja pp $Is/3R Ӻ-Yj+L;.0ŔI$Av? #!5"aʄj}UKmɽH$IjCYs?h$IDl843.v}m7UiI=&=0Lg0$I4: embe` eQbm0u? $IT!Sƍ'-sv)s#C0:XB2a w I$zbww{."pPzO =Ɔ\[ o($Iaw]`E).Kvi:L*#gР7[$IyGPI=@R 4yR~̮´cg I$I/<tPͽ hDgo 94Z^k盇΄8I56^W$I^0̜N?4*H`237}g+hxoq)SJ@p|` $I%>-hO0eO>\ԣNߌZD6R=K ~n($I$y3D>o4b#px2$yڪtzW~a $I~?x'BwwpH$IZݑnC㧄Pc_9sO gwJ=l1:mKB>Ab<4Lp$Ib o1ZQ@85b̍ S'F,Fe,^I$IjEdù{l4 8Ys_s Z8.x m"+{~?q,Z D!I$ϻ'|XhB)=…']M>5 rgotԎ 獽PH$IjIPhh)n#cÔqA'ug5qwU&rF|1E%I$%]!'3AFD/;Ck_`9 v!ٴtPV;x`'*bQa w I$Ix5 FC3D_~A_#O݆DvV?<qw+I$I{=Z8".#RIYyjǪ=fDl9%M,a8$I$Ywi[7ݍFe$s1ՋBVA?`]#!oz4zjLJo8$I$%@3jAa4(o ;p,,dya=F9ً[LSPH$IJYЉ+3> 5"39aZ<ñh!{TpBGkj}Sp $IlvF.F$I z< '\K*qq.f<2Y!S"-\I$IYwčjF$ w9 \ߪB.1v!Ʊ?+r:^!I$BϹB H"B;L'G[ 4U#5>੐)|#o0aڱ$I>}k&1`U#V?YsV x>{t1[I~D&(I$I/{H0fw"q"y%4 IXyE~M3 8XψL}qE$I[> nD?~sf ]o΁ cT6"?'_Ἣ $I>~.f|'!N?⟩0G KkXZE]ޡ;/&?k OۘH$IRۀwXӨ<7@PnS04aӶp.:@\IWQJ6sS%I$e5ڑv`3:x';wq_vpgHyXZ 3gЂ7{{EuԹn±}$I$8t;b|591nءQ"P6O5i }iR̈́%Q̄p!I䮢]O{H$IRϻ9s֧ a=`- aB\X0"+5"C1Hb?߮3x3&gşggl_hZ^,`5?ߎvĸ%̀M!OZC2#0x LJ0 Gw$I$I}<{Eb+y;iI,`ܚF:5ܛA8-O-|8K7s|#Z8a&><a&/VtbtLʌI$I$I$I$I$I$IRjDD%tEXtdate:create2022-05-31T04:40:26+00:00!Î%tEXtdate:modify2022-05-31T04:40:26+00:00|{2IENDB`Mini Shell

HOME


Mini Shell 1.0
DIR:/usr/share/zsh/5.5.1/functions/
Upload File :
Current File : //usr/share/zsh/5.5.1/functions/_tmux
#compdef tmux

# tmux <http://tmux.github.io> completion for zsh <http://zsh.sf.net>.
#
# Configuration:
#
# - On some OSs, the directory for tmux's server sockets may not be
#   the default (which is /tmp/tmux-<uid>/), but say
#   /var/run/tmux/tmux-<uid>, in which case the completion for
#   'tmux -L <tab>' will not be able to find the sockets in the default
#   location (debian does this, for instance); tell _tmux the right place
#   to look:
#       % zstyle ':completion:*:*:tmux:*:sockets' socketdir "/var/run/tmux/tmux-${UID}"
#
# - tmux knows a *lot* of sub-commands, hence 'tmux <tab>' returns a lot
#   of possible completions. _tmux knows about all commands and their aliases.
#   By default, both are offered. If you do not care about the aliases, do this:
#       % zstyle ':completion:*:*:tmux:*:subcommands' mode 'commands'
#
#   The same can be done to only return aliases by setting the above style
#   to 'aliases'. The default value is 'both' (but actually every value
#   different from 'commands' and 'aliases' will have the same effect).
#
#   'lsw' is an alias for 'list-windows' for example; note that not all
#   commands have aliases. So probably, either the default 'both' or
#   'commands' makes most sense for this style.
#
# - For finer grained control over what is suggested as possible completions,
#   the 'ignored-patterns' style may be used; suppose you think that only
#   '*-window' or '*-windows' are worth being completed. You would get that
#   behaviour like this:
#       % zstyle ':completion:*:*:tmux:*:subcommands' ignored-patterns '^*-window(|s)'
#
#   Some tmux commands currently do not work if called from a shell prompt,
#   so it would make sense to ignore them per default (at the time of writing,
#   those commands are choose-{session,client,window}, confirm-before and
#   find-window. This would ignore them:
#       % zstyle ':completion:*:*:tmux:*:subcommands' ignored-patterns \
#                'choose-*' 'confirm-before' 'find-window'
#
# The configuration for subcommand completions may be done in
# this context: ':completion:*:*:tmux-<sub-command>:*:*'
#
# TODO:
#
#   - Implement __tmux-format
#   - Implement __tmux-style (possibly using existing helpers like
#     __tmux-attributes and __tmux-colours)
#   - in _tmux-list-panes, use __tmux-windows or __tmux-sessions
#     depending on -s is among the sub-commands current command line.

# Global variables; setup the first time _tmux is called.
# For $_tmux_commands[] generation, see the very end of this file.
typeset -ga _tmux_commands=() _tmux_aliases=()
typeset -gA _tmux_aliasmap

_tmux_aliasmap=(
    # clients and sessions
    attach      attach-session
    detach      detach-client
    has         has-session
    lockc       lock-client
    locks       lock-session
    lsc         list-clients
    lscm        list-commands
    ls          list-sessions
    new         new-session
    refresh     refresh-client
    rename      rename-session
    showmsgs    show-messages
    source      source-file
    start       start-server
    suspendc    suspend-client
    switchc     switch-client

    # windows and panes
    breakp      break-pane
    capturep    capture-pane
    displayp    display-panes
    findw       find-window
    joinp       join-pane
    killp       kill-pane
    killw       kill-window
    last        last-window
    lastp       last-pane
    linkw       link-window
    lsp         list-panes
    lsw         list-windows
    movep       move-pane
    movew       move-window
    neww        new-window
    nextl       next-layout
    next        next-window
    pipep       pipe-pane
    prev        previous-window
    prevl       previous-layout
    renamew     rename-window
    resizep     resize-pane
    respawnp    respawn-pane
    respawnw    respawn-window
    rotatew     rotate-window
    selectl     select-layout
    selectp     select-pane
    selectw     select-window
    splitw      split-window
    swapp       swap-pane
    swapw       swap-window
    unlinkw     unlink-window

    # key bindings
    bind        bind-key
    lsk         list-keys
    send        send-keys
    unbind      unbind-key

    # options
    set         set-option
    setw        set-window-option
    show        show-options
    showw       show-window-options

    # environment
    setenv      set-environment
    showenv     show-environment

    # status line
    confirm     confirm-before
    display     display-message

    # buffers
    clearhist   clear-history
    deleteb     delete-buffer
    lsb         list-buffers
    loadb       load-buffer
    pasteb      paste-buffer
    saveb       save-buffer
    setb        set-buffer
    showb       show-buffer

    # miscellaneous
    if          if-shell
    lock        lock-server
    run         run-shell
    info        server-info
    wait        wait-for
)

# --- Sub-command functions ---
# These *must* be called _tmux-*(); The description generation relies on
# them being named that way. *No* other functions may match that pattern.
# Other utility functions should be named __tmux-*() (see below).
#
# Another thing, the description generation needs, is handling of
# $tmux_describe: If that parameter is non-empty, the sub-command function
# should only print a description of the sub-command it handles and return
# immediately after doing so.
#
# To add support for a new sub-command, you only have to add a new
# _tmux-<foo>() function below (preferably alphabetically sorted), that
# behaves like described above; and add a alias->command pair in the
# _tmux_aliasmap associative array above (if the command in fact has an
# alias). The rest should just work[tm].

_tmux-attach-session() {
  [[ -n ${tmux_describe} ]] && print "attach or switch to a session" && return

  _arguments -s \
    '-c+[specify working directory for the session]:directory:_directories' \
    '-d[detach other clients attached to target session]' \
    '-r[put the client into read-only mode]' \
    '-t+[specify target session]:target session: __tmux-sessions-separately' \
    "-E[don't apply update-environment option]"
}

_tmux-bind-key() {
  [[ -n ${tmux_describe} ]] && print "bind a key to a command" && return
  _arguments -s -A "-*" \
    '-c[bind to command mode instead of normal mode]' \
    '-n[make the binding work without the need for the prefix key]' \
    '-r[the key may repeat]' \
    '-T+[specify key table for the binding]:key table' \
    '1:key' \
    '*:::template:= _tmux'
}

_tmux-break-pane() {
  [[ -n ${tmux_describe} ]] && print "break a pane from an existing into a new window" && return
  _arguments -s \
    "-d[don't make the new window become the active one]" \
    '-F+[specify output format]:format:__tmux-format' \
    '-P[print information of new window after it has been created]' \
    '-n+[specify window name]:name' \
    '-s+[specify source pane]:pane:__tmux-panes' \
    '-t+[specify destination window]:pane:__tmux-panes'
}

_tmux-capture-pane() {
  [[ -n ${tmux_describe} ]] && print "capture the contents of a pane to a buffer" && return
  _arguments -s \
    '-a[use alternate screen]' \
    '(-p)-b+[choose target buffer]:target buffer:__tmux-buffers' \
    '-C[escape non-printable characters as octal \\ooo]' \
    '-e[include escape sequences for attributes etc]' \
    '-E[specify last line to capture]:line number (- means last line)' \
    '-J[join wrapped lines and preserve trailing space]' \
    '-q[ignore errors when trying to access alternate screen]' \
    '(-b)-p[print data to stdout]' \
    '-P[only capture beginnings of as-yet incomplete escape sequences]' \
    '-S[specify start line to capture]:first line (- means start of scrollback)' \
    '-t+[choose source pane]:source pane:__tmux-panes'
}

_tmux-choose-buffer() {
  [[ -n ${tmux_describe} ]] && print "put a pane into buffer choice mode" && return
  _arguments -s \
    '-N[start without the preview]' \
    '-F+[specify format for each list item]:format:__tmux-formats' \
    '-f+[filter items]:filter format:__tmux-formats' \
    '-O+[initial sort order]:order:(time name size)' \
    '-t+[specify target window]:session:__tmux-windows' \
    '*:::template:= _tmux'
}

_tmux-choose-client() {
  [[ -n ${tmux_describe} ]] && print "put a window into client choice mode" && return
  _arguments -s \
    '-N[start without the preview]' \
    '-F+[specify format for each list item]:format:__tmux-formats' \
    '-f+[filter items]:filter format:__tmux-formats' \
    '-O+[initial sort order]:order:(time name size)' \
    '-t+[specify target window]:session:__tmux-windows' \
    '*:::template:= _tmux'
}

_tmux-choose-tree() {
  [[ -n ${tmux_describe} ]] && print "put a window into tree choice mode" && return
  _arguments -s \
    '-N[start without the preview]' \
    '-F+[specify format for each list item]:format:__tmux-formats' \
    '-f+[filter items]:filter format:__tmux-formats' \
    '-O+[initial sort order]:order:(time name size)' \
    '-s[choose among sessions]' \
    '-t+[specify target window]:session:__tmux-windows' \
    '-w[choose among windows]' \
    '*:::template:= _tmux'
}

_tmux-clear-history() {
  [[ -n ${tmux_describe} ]] && print "remove and clear history for a pane" && return
  _arguments '-t+[specify target pane]:pane:__tmux-panes'
}

_tmux-clock-mode() {
  [[ -n ${tmux_describe} ]] && print "enter clock mode" && return
  _arguments '-t+[specify target pane]:pane:__tmux-panes'
}

_tmux-command-prompt() {
  [[ -n ${tmux_describe} ]] && print "open the tmux command prompt in a client" && return
  _arguments -s \
    '-1[only accept one key press]' \
    '-N' \
    '-i[execute the command every time the prompt input changes]' \
    '-I+[specify list of initial inputs]:initial-text (comma-separated list)' \
    '-p+[specify list of prompts]:prompts (comma-separated list)' \
    '-t+[specify target client]:client:__tmux-clients' \
    '*:::template:= _tmux'
}

_tmux-confirm-before() {
  [[ -n ${tmux_describe} ]] && print "run a command but ask for confirmation before" && return
  _arguments -s \
    '-p+[specify prompt]:prompt string' \
    '-t+[specify target client]:client:__tmux-clients' \
    '*:::command:= _tmux'
}

_tmux-copy-mode() {
  [[ -n ${tmux_describe} ]] && print "enter copy mode" && return
  _arguments -s \
    '-t+[specify target pane]:pane:__tmux-panes' \
    '-u[scroll up one page]' \
    '-M[begin a mouse drag]'
}

_tmux-delete-buffer() {
  [[ -n ${tmux_describe} ]] && print "delete a paste buffer" && return
  _arguments '-b+[specify target buffer name]:buffer:__tmux-buffers'
}

_tmux-detach-client() {
  [[ -n ${tmux_describe} ]] && print "detach a client from the server" && return
  _arguments -s \
    '-a[kill all clients except for the named by -t]' \
    '-P[send SIGHUP to parent process]' \
    '-E+[run specified shell command to replace the client]:shell command:_cmdstring' \
    '-s+[specify target session and kill its clients]:session:__tmux-sessions-attached' \
    '-t+[specify target client]:client:__tmux-clients'
}

_tmux-display-message() {
  [[ -n ${tmux_describe} ]] && print "display a message in the status line" && return
  _arguments -s -S \
    '-c+[specify target client]:client:__tmux-clients' \
    '-p[print message to stdout]' \
    '-t+[specify target client]:client:__tmux-clients' \
    '-F+[specify output format]:format:__tmux-formats' \
    ':message'
}

_tmux-display-panes() {
  [[ -n ${tmux_describe} ]] && print "display an indicator for each visible pane" && return
  _arguments -S \
    '-d+[time to show indicator for]:duration (ms)' \
    '-t+[specify target client]:client:__tmux-clients' \
    '*:::command:= _tmux'
}

_tmux-find-window() {
  [[ -n ${tmux_describe} ]] && print "search for a pattern in windows" && return
  _arguments -s \
    '-C[match visible contents]' \
    '-N[match window name]' \
    '-T[match window title]' \
    '-t+[specify target window]:window:__tmux-windows' \
    ':window search pattern'
}

_tmux-has-session() {
  [[ -n ${tmux_describe} ]] && print "check and report if a session exists on the server" && return
  _arguments '-t+[specify target session]:session:__tmux-sessions'
}

_tmux-if-shell() {
  [[ -n ${tmux_describe} ]] && print "execute a tmux command if a shell-command succeeded" && return
  local curcontext="$curcontext" state line ret=1
  _arguments -C -s \
    '-b[run shell command in background]' \
    "-F[don't execute shell command but use it as a string-value]" \
    '-t+[specify target pane]:pane:__tmux-panes' \
    '1:shell command:_cmdstring' \
    '2:tmux command (success):->tmuxcmd' \
    '3:tmux command (failure):->tmuxcmd' && ret=0
  if [[ -n $state ]]; then
    compset -q
    _tmux && ret=0
  fi
}

_tmux-join-pane() {
  [[ -n ${tmux_describe} ]] && print "split a pane and move an existing one into the new space" && return
  _arguments -s \
    '-b[join source pane left of or above target pane]' \
    "-d[don't make the new window become the active one]" \
    '-h[split horizontally]' \
    '-v[split vertically]' \
    "-l+[define new pane's size]: :_guard '[0-9]#' 'numeric value'" \
    "-p+[define new pane's size in percent]: :_guard '[0-9]#' 'numeric value'" \
    '-s+[specify source pane]:pane:__tmux-panes' \
    '-t+[specify target pane]:pane:__tmux-panes'
}

_tmux-kill-pane() {
  [[ -n ${tmux_describe} ]] && print "destroy a given pane" && return
  _arguments -s \
    '-a[kill all panes except the one specified by -t]' \
    '-t+[specify target pane]:pane:__tmux-panes'
}

_tmux-kill-server() {
  [[ -n ${tmux_describe} ]] && print "kill clients, sessions and server" && return
  __tmux-nothing-else
}

_tmux-kill-session() {
  [[ -n ${tmux_describe} ]] && print "destroy a given session" && return
  _arguments -s \
    '-a[kill all session except the one specified by -t]' \
    '-t+[specify target session]:session:__tmux-sessions' \
    '-C[clear alerts (bell, activity, silence) in all windows linked to the session]'
}

_tmux-kill-window() {
  [[ -n ${tmux_describe} ]] && print "destroy a given window" && return
  _arguments -s \
    '-a[kill all windows except the one specified by -t]' \
    '-t+[specify target window]:window:__tmux-windows'
}

_tmux-last-pane() {
  [[ -n ${tmux_describe} ]] && print "select the previously selected pane" && return
  _arguments -s \
    '-d[disable input to the pane]' \
    '-e[enable input to the pane]' \
    '-t+[specify session]:session:__tmux-sessions'
}

_tmux-last-window() {
  [[ -n ${tmux_describe} ]] && print "select the previously selected window" && return
  _arguments '-t+[specify session]:session:__tmux-sessions'
}

_tmux-link-window() {
  [[ -n ${tmux_describe} ]] && print "link a window to another" && return
  _arguments -s \
    "-d[don't make the new window become the active one]" \
    '-k[kill the target window if it exists]' \
    '-s+[specify source window]:window:__tmux-windows' \
    '-t+[specify destination window]:window:__tmux-windows'
}

_tmux-list-buffers() {
  [[ -n ${tmux_describe} ]] && print "list paste buffers of a session" && return
  _arguments '-F+[specify output format]:format:__tmux-formats'
}

_tmux-list-clients() {
  [[ -n ${tmux_describe} ]] && print "list clients attached to server" && return
  _arguments -s \
    '-F+[specify output format]:format:__tmux-formats' \
    '-t+[specify session]:session:__tmux-sessions'
}

_tmux-list-commands() {
  [[ -n ${tmux_describe} ]] && print "list supported sub-commands" && return
  _arguments '-F+[specify format]:format'
}

_tmux-list-keys() {
  [[ -n ${tmux_describe} ]] && print "list all key-bindings" && return
  _arguments -s \
    '-T+[specify key table]:key table'
}

_tmux-list-panes() {
  [[ -n ${tmux_describe} ]] && print "list panes of a window" && return
  local -a args
  if (( ${+words[(r)-*s*]} )); then
    args=( '-t+[specify target session]:session:__tmux-sessions' )
  else
    args=( '-t+[specify target window]:window:__tmux-windows' )
  fi
  _arguments -s $args \
    '-a[list all panes the server possesses]' \
    '-F+[specify output format]:format:__tmux-formats' \
    '-s[if specified, -t chooses a session]'
}

_tmux-list-sessions() {
  [[ -n ${tmux_describe} ]] && print "list sessions managed by server" && return
  _arguments '-F+[specify output format]:format:__tmux-formats'
}

_tmux-list-windows() {
  [[ -n ${tmux_describe} ]] && print "list windows of a session" && return
  _arguments -s \
    '-a[list all windows the tmux server possesses]' \
    '-F[specify output format]:format:__tmux-formats' \
    '-t+[specify session]:session:__tmux-sessions'
}

_tmux-load-buffer() {
  [[ -n ${tmux_describe} ]] && print "load a file into a paste buffer" && return
  _arguments -A "-*" -S \
    '-b+[specify target buffer name]:buffer:__tmux-buffers' \
    '1:file:_files'
}

_tmux-lock-client() {
  [[ -n ${tmux_describe} ]] && print "lock a client" && return
  _arguments '-t+[specify client]:client:__tmux-clients'
}

_tmux-lock-server() {
  [[ -n ${tmux_describe} ]] && print "lock all clients attached to the server" && return
  __tmux-nothing-else
}

_tmux-lock-session() {
  [[ -n ${tmux_describe} ]] && print "lock all clients attached to a session" && return
  _arguments '-t+[specify session]:session:__tmux-sessions'
}

_tmux-move-pane() {
  [[ -n ${tmux_describe} ]] && print "move a pane into a new space" && return
  _arguments -s \
    '-b[join source pane left of or above target pane]' \
    "-d[don't make the new window become the active one]" \
    '-h[split horizontally]' \
    '-v[split vertically]' \
    "-l+[define new pane's size]:numeric value" \
    "-p+[define new pane's size in percent]:numeric value" \
    '-s+[specify source pane]:pane:__tmux-panes' \
    '-t+[specify target pane]:pane:__tmux-panes'
}

_tmux-move-window() {
  [[ -n ${tmux_describe} ]] && print "move a window to another" && return
  _arguments -s \
    "-d[don't make the new window become the active one]" \
    '-k[kill the target window if it exists]' \
    '-s+[specify source window]:window:__tmux-windows' \
    '-r[renumber windows in session in sequential order]' \
    '-t+[specify destination window]:window:__tmux-windows'
}

_tmux-new-session() {
  [[ -n ${tmux_describe} ]] && print "create a new session" && return
  _arguments -s -A "-*" -S \
    '-A[attach to existing session if it already exists]' \
    '-c+[specify working directory for the session]:directory:_directories' \
    "-d[don't attach new session to current terminal]" \
    "-D[in case of -A behave like attach-session's -d]" \
    "-E[don't apply update-environment option]" \
    '-F+[specify output format]:format:__tmux-formats' \
    '-n+[specify initial window name]:window name' \
    '-P[print information about new session after it is created]' \
    '-s+[name the session]:session name:__tmux-sessions' \
    '-t+[specify target session]:session:__tmux-sessions' \
    '-x[specify width]:width' \
    '-y[specify height]:height' \
    '*:: :_cmdambivalent'
}

_tmux-new-window() {
  [[ -n ${tmux_describe} ]] && print "create a new window" && return
  _arguments -s -A "-*" -S \
    '-a[insert new window at next free index from -t]' \
    '-c+[specify working directory for the session]:directory:_directories' \
    "-d[don't make the new window become the active one]" \
    '-F+[specify output format]:format:__tmux-formats' \
    '-k[destroy it if the specified window exists]' \
    '-n+[specify a window name]:window name' \
    '-P[print information about new window after it is created]' \
    '-t+[specify target window]:window:__tmux-windows' \
    '*:: :_cmdambivalent'
}

_tmux-next-layout() {
  [[ -n ${tmux_describe} ]] && print "move a window to the next layout" && return
  _arguments '-t+[specify target window]:window:__tmux-windows'
}

_tmux-next-window() {
  [[ -n ${tmux_describe} ]] && print "move to the next window in a session" && return
  _arguments -s \
    '-a[move to the next window with an alert]' \
    '-t+[specify target session]:session:__tmux-sessions'
}

_tmux-paste-buffer() {
  [[ -n ${tmux_describe} ]] && print "insert a paste buffer into the window" && return
  _arguments -s \
    '-b+[specify buffer]:source buffer:__tmux-buffers' \
    '-d[remove buffer from stack after pasting]' \
    '-p[use bracketed paste mode if the application requested it]' \
    "-r[don't replace LF with CR when pasting]" \
    '-s+[specify separator]:separator' \
    '-t+[specify target window]:window:__tmux-windows'
}

_tmux-pipe-pane() {
  [[ -n ${tmux_describe} ]] && print "pipe output from a pane to a shell command" && return
  _arguments -s -A "-*" -S \
    '-o[only open a pipe if none is currently opened]' \
    '-t+[specify target pane]:pane:__tmux-panes' \
    ':shell command:_cmdstring'
}

_tmux-previous-layout() {
  [[ -n ${tmux_describe} ]] && print "move a window to the previous layout" && return
  _arguments '-t+[specify target window]:window:__tmux-windows'
}

_tmux-previous-window() {
  [[ -n ${tmux_describe} ]] && print "move to the previous window in a session" && return
  _arguments -s \
    '-a[move to the previous window with an alert]' \
    '-t+[specify target session]:session:__tmux-sessions'
}

_tmux-refresh-client() {
  [[ -n ${tmux_describe} ]] && print "refresh a client" && return
  _arguments -s \
    "-S[only update the client's status bar]" \
    '-t+[specify target client]:client:__tmux-clients' \
    '-C+:size'
}

_tmux-rename-session() {
  [[ -n ${tmux_describe} ]] && print "rename a session" && return
  _arguments -s -A "-*" -S \
    '-t+[specify target session]:session:__tmux-sessions' \
    ':new session name'
}

_tmux-rename-window() {
  [[ -n ${tmux_describe} ]] && print "rename a window" && return
  _arguments -s -A "-*" -S \
    '-t+[specify target window]:window:__tmux-windows' \
    ':new window name'
}

_tmux-resize-pane() {
  [[ -n ${tmux_describe} ]] && print "resize a pane" && return
  _arguments -s -A "-*" -S \
    '-D[resize downward]' \
    '-L[resize to the left]' \
    '-M[begin mouse resizing]' \
    '-R[resize to the right]' \
    '-U[resize upward]' \
    '-t+[specify target pane]:pane:__tmux-panes' \
    '-x+[specify width]:width' \
    '-y+[specify height]:height' \
    '-Z[toggle zoom of pane]' \
    ':adjustment'
}

_tmux-respawn-pane() {
  [[ -n ${tmux_describe} ]] && print "reuse a pane in which a command has exited" && return
  _arguments -s -A "-*" -S \
    '-c+[specify a new working directory for the pane]:directory:_directories' \
    '-k[kill window if it is in use]' \
    '-t+[specify target pane]:pane:__tmux-pane' \
    ':command:_cmdambivalent'
}

_tmux-respawn-window() {
  [[ -n ${tmux_describe} ]] && print "reuse a window in which a command has exited" && return
  _arguments -s -A "-*" -S \
    '-c+[specify a new working directory for the window]:directory:_directories' \
    '-k[kill window if it is in use]' \
    '-t+[specify target window]:window:__tmux-windows' \
    ':command:_cmdambivalent'
}

_tmux-rotate-window() {
  [[ -n ${tmux_describe} ]] && print "rotate positions of panes in a window" && return
  _arguments -s \
    '-D[rotate downward]' \
    '-U[rotate upward]' \
    '-t+[specify target window]:window:__tmux-windows'
}

_tmux-run-shell() {
  [[ -n ${tmux_describe} ]] && print "execute a command without creating a new window" && return
  _arguments -s -A "-*" -S \
    '-b[run shell command in background]' \
    '-t+[specify target pane]:pane:__tmux-panes' \
    ':command:_cmdstring'
}

_tmux-save-buffer() {
  [[ -n ${tmux_describe} ]] && print "save a paste buffer to a file" && return
  _arguments -s \
    '-a[append to rather than overwriting file]' \
    '-b+[specify a target buffer index]:buffer:__tmux-buffers'
}

_tmux-select-layout() {
  [[ -n ${tmux_describe} ]] && print "choose a layout for a window" && return
  _arguments -s -A "-*" -S \
    '-n[behave like next-layout]' \
    '-o[revert to previous layout]' \
    '-p[behave like previous-layout]' \
    '-t+[specify a target window]:target window:__tmux-windows' \
    ':layout:(even-horizontal even-vertical main-horizontal main-vertical tiled)'
}

_tmux-select-pane() {
  [[ -n ${tmux_describe} ]] && print "make a pane the active one in the window" && return
  _arguments -s \
    '-D[move to the pane below target]' \
    '-d[disable input to the pane]' \
    '-e[enable input to the pane]' \
    '-g[show current pane style]' \
    '-l[behave like last-pane]' \
    '-L[move to the pane left of target]' \
    '-M[clear marked pane]' \
    '-m[set marked pane]' \
    '-R[move to the pane right of target]' \
    '-U[move to the pane above target]' \
    '-P+[set pane style]:style:__tmux-style' \
    '-T+[set the pane title]:title' \
    '-t+[specify target pane]:pane:__tmux-panes'
}

_tmux-select-window() {
  [[ -n ${tmux_describe} ]] && print "select a window" && return
  _arguments -s \
    '-l[behave like last-window]' \
    '-n[behave like next-window]' \
    '-p[behave like previous-window]' \
    '-T[if selected window is the current behave like last-window]' \
    '-t+[specify target window]:window:__tmux-windows'
}

_tmux-send-keys() {
  [[ -n ${tmux_describe} ]] && print "send key(s) to a window" && return
  _arguments -s -A "-*" -S \
    '-l[disable key name lookup and send data literally]' \
    '-R[reset terminal state]' \
    '-M[pass through a mouse event]' \
    '-X[send a command into copy mode]' \
    '-N+[specify repeat count]:repeat count' \
    '-t+[specify target pane]:pane:__tmux-panes' \
    '*:key'
}

_tmux-send-prefix() {
  [[ -n ${tmux_describe} ]] && print "send the prefix key to a window" && return
  _arguments -s \
    '-2[send secondary prefix key]' \
    '-t+[specify target pane]:pane:__tmux-panes'
}

_tmux-server-info() {
  [[ -n ${tmux_describe} ]] && print "show server information" && return
  __tmux-nothing-else
}

_tmux-set-buffer() {
  [[ -n ${tmux_describe} ]] && print "set contents of a paster buffer" && return
  _arguments -s -A "-*" -S \
    '-a[append to rather than overwriting target buffer]' \
    '-b+[specify target buffer index]:pane:__tmux-buffers' \
    '-n+[specify new buffer name]:buffer-name' \
    ':data'
}

_tmux-set-environment() {
  [[ -n ${tmux_describe} ]] && print "(un)set an environment variable" && return
  local mode=session action=add
  local curcontext="$curcontext" state line ret=1
  typeset -A opt_args
  _arguments -C -s -A "-*" -S : \
    '(-t)-g[modify global environment]' \
    '(-u)-r[remove variable before starting new processes]' \
    '(-r)-u[unset a variable]' \
    '(-g)-t[specify target session]:target session:__tmux-sessions' \
    ': :->name' '(-u -r)2: :->value' && ret=0

  if (( ${+opt_args[-g]} )); then
      mode=global
  fi
  if (( ${+opt_args[-u]} )); then
      action=unset
  fi
  if (( ${+opt_args[-r]} )); then
      action=remove
  fi

  # TODO: the exclusion "(-g -r)2:" doesn't work, so simulate it here
  if [[ $action == (remove|unset) ]] && [[ $state == value ]]; then
      __tmux-nothing-else
  else
      __tmux-environment-variables $mode $state $action && ret=0
  fi
  return ret
}

_tmux-set-option() {
  [[ -n ${tmux_describe} ]] && print "set a session option" && return
  local mode=session
  local curcontext="$curcontext" state line ret=1
  typeset -A opt_args
  _arguments -C -s : \
    '-a[append to string options]' \
    '-F[expand formats in the option value]' \
    '-g[set a global session option]' \
    '-o[prevent setting of an option that is already set]' \
    '-q[suppress errors about unknown or ambiguous options]' \
    '-u[unset a non-global option]' \
    '-w[change window (not session) options]' \
    '-s[change server (not session) options]' \
    '-t+[specify target session]:target session:__tmux-sessions' \
    '*:: :->name_or_value' && ret=0

  if (( ${+opt_args[-w]} )); then
    mode=window
  elif (( ${+opt_args[-s]} )); then
    mode=server
  fi
  __tmux-options-complete ${mode} ${state} && ret=0
  return ret
}

_tmux-set-window-option() {
  [[ -n ${tmux_describe} ]] && print "set a window option" && return
  local curcontext="$curcontext" state line ret=1
  typeset -A opt_args
  _arguments -C -s : \
    '-a[append to string options]' \
    '-F[expand formats in the option value]' \
    '-g[set a global window option]' \
    '-o[prevent setting of an option that is already set]' \
    '-q[suppress errors about unknown or ambiguous options]' \
    '-u[unset a non-global option]' \
    '-t+[specify target window]:target window:__tmux-windows' \
    '*:: :->name_or_value' && ret=0
  __tmux-options-complete window ${state} && ret=0
  return ret
}

_tmux-set-hook() {
  [[ -n ${tmux_describe} ]] && print "set a hook to a command" && return
  _arguments -s \
    '-g[add hook to global list]' \
    '-u[unset a hook]' \
    '-t+[specify target session]:session:__tmux-sessions' \
    ':hook name:_tmux_hooks' \
    '*:::command:= _tmux'
}

_tmux-show-hooks() {
  [[ -n ${tmux_describe} ]] && print "show the global list of hooks" && return
  _arguments -s -S -A "-*" \
    '-g[show global list of hooks]' \
    '-t+[specify target session]:session:__tmux-sessions' \
}

_tmux-show-buffer() {
  [[ -n ${tmux_describe} ]] && print "display the contents of a paste buffer" && return
  _arguments '-b[specify target buffer index]:pane:->buffer'
}

_tmux-show-environment() {
  [[ -n ${tmux_describe} ]] && print "display the environment" && return
  local mode=session
  local curcontext="$curcontext" state line ret=1
  typeset -A opt_args
  _arguments -C -A "-*" -s : \
    '(-t)-g[show global environment]' \
    '-s[format output as Bourne shell commands]' \
    '(-g)-t+[specify target session]:target session:__tmux-sessions' \
    '1:: :->name' && ret=0

  if (( ${+opt_args[-g]} )); then
      mode=global
  fi

  __tmux-environment-variables $mode $state show && ret=0
  return ret
}

_tmux-show-messages() {
  [[ -n ${tmux_describe} ]] && print "show client's message log" && return
  _arguments -s \
    '-J[show debugging information about running jobs]' \
    '-T[show debugging information about involved terminals]' \
    '-t+[specify target client]:client:__tmux-clients'
}

_tmux-show-options() {
  [[ -n ${tmux_describe} ]] && print "show session options" && return
  local mode=session
  local curcontext="$curcontext" state line ret=1
  typeset -A opt_args
  _arguments -C -s : \
    '-g[show global options]' \
    '-q[suppress errors about unknown or ambiguous options]' \
    '-s[show server options]' \
    '-v[show only the option value, not the name]' \
    '-w[show window options]' \
    '-t+[specify target session]:target session:__tmux-sessions' \
    '*:: :->name_or_value' && ret=0

  if (( ${+opt_args[-w]} )); then
    mode=window
  elif (( ${+opt_args[-s]} )); then
    mode=server
  fi
  __tmux-options-complete ${mode} ${state} && ret=0
  return ret
}

_tmux-show-window-options() {
  [[ -n ${tmux_describe} ]] && print "show window options" && return
  local curcontext="$curcontext" state line ret=1
  typeset -A opt_args
  _arguments -C -s : \
    '-g[show global options]' \
    '-v[show only the option value, not the name]' \
    '-t+[specify target window]:target window:__tmux-windows' \
    '*:: :->name_or_value' && ret=0
  __tmux-options-complete window ${state} && ret=0
  return ret
}

_tmux-source-file() {
  [[ -n ${tmux_describe} ]] && print "execute tmux commands from a file" && return
  _arguments \
    "-q[don't report error if path doesn't exist]" \
    '*:path:_directories'
}

_tmux-split-window() {
  [[ -n ${tmux_describe} ]] && print "splits a pane into two" && return
  _arguments -s \
    '-b[create new pane left of or above target pane]' \
    "-d[don't make the new window become the active one]" \
    '-F+[specify output format]:format:__tmux-formats' \
    '-f[create new pane spanning full window width or height]' \
    '-h[split horizontally]' \
    '-v[split vertically]' \
    "-l[define new pane's size]:size" \
    "-p[define new pane's size in percent]:size (percentage)" \
    '-t+[specify target pane]:pane:__tmux-panes' \
    ':command:_cmdambivalent'
  # Yes, __tmux-panes is correct here. The behaviour was changed
  # in recent tmux versions and makes more sense. Except that
  # changing the command's name might annoy users. So it stays like
  # this.
}

_tmux-start-server() {
  [[ -n ${tmux_describe} ]] && print "start a tmux server" && return
  __tmux-nothing-else
}

_tmux-suspend-client() {
  [[ -n ${tmux_describe} ]] && print "suspend a client" && return
  _arguments '-t+[specify destination client]:client:__tmux-clients'
}

_tmux-swap-pane() {
  [[ -n ${tmux_describe} ]] && print "swap two panes" && return
  _arguments -s \
    '-D[move pane down]' \
    '-U[move pane up]' \
    "-d[don't change the active pane]" \
    '-s+[specify source pane]:pane:__tmux-panes' \
    '-t+[specify destination pane]:pane:__tmux-panes'
}

_tmux-swap-window() {
  [[ -n ${tmux_describe} ]] && print "swap two windows" && return
  _arguments -s \
    "-d[don't make the new window become the active one]" \
    '-s+[specify source window]:window:__tmux-windows' \
    '-t+[specify destination window]:window:__tmux-windows'
}

_tmux-switch-client() {
  [[ -n ${tmux_describe} ]] && print "switch the client to another session" && return
  _arguments -s \
    '-c+[specify a target client]:client:__tmux-clients' \
    "-E[don't apply update-environment option]" \
    '-l[move client to last session]' \
    '-n[move client to next session]' \
    '-p[move client to previous session]' \
    '-r[toggle read-only flag of client]' \
    '-t+[specify target window]:window:__tmux-windows'
}

_tmux-unbind-key() {
  [[ -n ${tmux_describe} ]] && print "unbind a key" && return
  local curcontext="$curcontext" state line keytable
  local -a ow

  ow=( "${words[@]}" )
  _arguments -C -s \
    '-a[remove all key bindings]' \
    '-n[remove a non-prefix binding]' \
    '-T[specify key table]:key table' \
    '*:: :->boundkeys'

    [[ ${state} != 'boundkeys' ]] && return
    keytable="$(__tmux-get-optarg -t "${ow[@]}")"
    if [[ -n ${keytable} ]]; then
        __tmux-bound-keys -t ${keytable}
        return
    fi
    __tmux-bound-keys
}

_tmux-unlink-window() {
  [[ -n ${tmux_describe} ]] && print "unlink a window" && return
  _arguments -s \
    '-k[kill the window if it is only in one session]' \
    '-t+[specify target window]:target window:__tmux-windows'
}

_tmux-wait-for() {
  [[ -n ${tmux_describe} ]] && print "wait for an event or trigger it" && return
  _arguments -s \
    '-L[lock the named channel]' \
    '-S[send signal to channel]' \
    '-U[unlock the named channel]' \
    ':event channel'
}

# --- Utility functions ---
# They should be called __tmux-*() and kept separate from the
# sub-command functions.

function __tmux-attributes() {
    local -a attr already
    attr=( default bright bold dim underscore blink reverse hidden italics )
    compset -P '*,'
    already=( ${(s<,>)IPREFIX} )
    _describe -t tmux-attribute 'tmux attribute' attr -S, -F already -q
}

function __tmux-buffers() {
    local expl
    local -a buffers

    if [[ ${(t)bopts} != *array* ]]; then
        local -a bopts; bopts=()
    fi

    buffers=( ${${(f)"$(command tmux 2> /dev/null list-buffers "${bopts[@]}")"}/:[ $'\t']##/:} )
    _describe -t buffers 'buffers' buffers
}

function __tmux-bound-keys() {
    local expl
    local -a keys

    keys=( ${${${${(f)"$(command tmux 2> /dev/null list-keys "$@")"}/:[ $'\t']##/:}/(#s)[ $'\t']##/}/(#s):/\\:} )
    _describe -t keys 'keys' keys
}

function __tmux-clients() {
    local expl
    local -a clients
    clients=( ${${(f)"$(command tmux 2> /dev/null list-clients)"}/:[ $'\t']##/:} )
    _describe -t clients 'clients' clients
}

function __tmux-environment-variables() {
    local mode="$1" state="$2" action="$3"

    local -a dash_g
    case $mode in
        (global) dash_g=(-g);;
        (session) dash_g=();;
        (*) return 1;; # bug in the caller
    esac

    local hint
    case $action in
        (add|remove) hint=" (or specify a new one)";;
        (unset|show) hint="";;
        (*) return 1;; # bug in the caller
    esac

    case ${state} in
        (name) 
            local -a vars_and_vals=( ${(@f)"$(command tmux 2>/dev/null show-env $dash_g)"} )
            local -a descriptions
            local k_v k v
            for k_v in $vars_and_vals; do
                k=${k_v%%=*}
                if [[ $k == -* ]]; then
                    k=${k#-}
                    v='(remove)'
                else
                    v=${k_v#*=}
                fi
                descriptions+=( "${k//:/\\:}:$v" )
            done
            # TODO: this if/else is because '_describe ${hint:+"-x"}' prints the "No matches" error in addition to the message.
            local msg="${dash_g[1]:+"global "}environment variables${hint}"
            if _describe -t parameters $msg descriptions; then
                :
            elif [[ -n $hint ]]; then
                _message $msg
            fi
            ;;
        (value)
            local var_and_val=${(@f)"$(command tmux 2>/dev/null show-env $dash_g -- ${(Q)words[-2]})"}
            # TODO: this if/else is because '_description -x' prints the "No matches" error in addition to the message.
            if [[ -n $var_and_val ]]; then
                local -a expl
                _description -x parameter-values expl "Value for ${words[-2]}"
                compadd "$expl[@]" - ${var_and_val#*=}
            else
                _message "Value for ${words[-2]}"
            fi
            ;;
        (*)
            return 1
            ;;
    esac
}

__tmux-formats() {
  _message 'not implemented yet'
}

function __tmux-colours() {
    local -a colnames
    colnames=( default black red green yellow blue magenta cyan white colourN:"replace N by a number between 0 and 255" )
    compset -P 'colour*'
    if [[ -z ${IPREFIX} ]]; then
        _describe -t tmux-colours 'colour' colnames
    else
        _message 'colour number 0..255'
    fi
}

_tmux_hooks() {
  _alternative \
    'hooks:hook name:(alert-activity alert-bell alert-silence client-attached client-detached client-resized client-session-changed pane-died pane-exited pane-set-clipboard session-created session-closed session-renamed window-linked window-renamed window-unlinked)' \
    'post-hooks:command post-hook:compadd - after-${_tmux_aliasmap}'
}

function __tmux-get-optarg() {
    local opt="$1"
    local -i i
    shift

    for (( i = 1; i <= $#; i++ )); do
        if [[ ${argv[$i]} == ${opt} ]]; then
            if [[ ${argv[$(( i + 1 ))]} != -* ]]; then
                print -- ${argv[$(( i + 1 ))]}
            fi
            return
        fi
    done
}

__tmux-nothing-else() {
  _message "no further arguments"
}

function __tmux-option-guard() {
    local mode opt guard int_guard
    mode="$1"
    opt="$2"
    shift; shift
    local -a options desc
    int_guard='_guard "[0-9]#" "'${opt}': numeric value"'
    if [[ ${mode} == 'session' ]]; then
        options=(
            'assume-paste-time:'${int_guard}
            'base-index:'${int_guard}
            'bell-action:DESC:any none current other'
            'bell-on-alert:DESC:on off'
            'default-command:MSG:command string'
            'default-shell:MSG:shell executable'
            'destroy-unattached:DESC:on off'
            'detach-on-destroy:DESC:on off'
            'display-panes-colour:__tmux-colours'
            'display-panes-active-colour:__tmux-colours'
            'display-panes-time:'${int_guard}
            'display-time:'${int_guard}
            'history-limit:'${int_guard}
            'lock-after-time:'${int_guard}
            'lock-command:MSG:command string'
            'message-command-style:__tmux-style'
            'message-style:__tmux-style'
            'mouse:DESC:on off'
            'prefix:MSG:primary prefix key'
            'prefix2:MSG:secondary prefix key'
            'renumber-windows:DESC:on off'
            'repeat-time:'${int_guard}
            'set-titles:DESC:on off'
            'set-titles-string:MSG:title format string'
            'status:DESC:on off'
            'status-interval:'${int_guard}
            'status-justify:DESC:left centre right'
            'status-keys:DESC:vi emacs'
            'status-left:MSG:format string'
            'status-left-length:'${int_guard}
            'status-left-style:__tmux-style'
            'status-position:DESC:top bottom'
            'status-right:MSG:format string'
            'status-right-length:'${int_guard}
            'status-right-style:__tmux-style'
            'status-style:__tmux-style'
            'update-environment:MSG:string listing env. variables'
            'visual-activity:DESC:on off'
            'visual-bell:DESC:on off'
            'visual-silence:DESC:on off'
            'word-separators:MSG:separator string'
        )
    elif [[ ${mode} == 'server' ]]; then
        options=(
            'buffer-limit:'${int_guard}
            'default-terminal:MSG:terminal string'
            'escape-time:'${int_guard}
            'exit-unattached:DESC:on off'
            'focus-events:DESC:on off'
            'history-file:_path-files -g "*(-.)"'
            'message-limit:'${int_guard}
            'quiet:DESC:on off'
            'set-clipboard:DESC:on off'
            'terminal-overrides:MSG:overrides string'
        )
    else
        options=(
            'aggressive-resize:DESC:on off'
            'allow-rename:DESC:on off'
            'alternate-screen:DESC:on off'
            'automatic-rename:DESC:on off'
            'automatic-rename-format:DESC:__tmux-format'
            'clock-mode-colour:__tmux-colours'
            'clock-mode-style:DESC:12 24'
            'force-height:'${int_guard}
            'force-width:'${int_guard}
            'main-pane-height:'${int_guard}
            'main-pane-width:'${int_guard}
            'mode-keys:DESC:vi emacs'
            'mode-style:__tmux-style'
            'monitor-activity:DESC:on off'
            'monitor-silence:DESC:on off'
            'other-pane-height:'${int_guard}
            'other-pane-width:'${int_guard}
            'pane-active-border-style:__tmux-style'
            'pane-base-index:'${int_guard}
            'pane-border-format:MSG:pane border status string'
            'pane-border-status:DESC:off top bottom'
            'pane-border-style:__tmux-style'
            'remain-on-exit:DESC:on off'
            'synchronize-panes:DESC:on off'
            'window-active-style:__tmux-style'
            'window-status-activity-style:__tmux-style'
            'window-status-bell-style:__tmux-style'
            'window-status-current-format:MSG:status format string'
            'window-status-current-style:__tmux-style'
            'window-status-format:MSG:status format string'
            'window-status-last-style:__tmux-style'
            'window-status-separator:MSG:separator string'
            'window-status-style:__tmux-style'
            'window-style:__tmux-style'
            'wrap-search:DESC:on off'
            'xterm-keys:DESC:on off'
        )
    fi

    guard=${(M)options:#$opt:*}
    if [[ -z ${guard} ]]; then
        _message "unknown ${mode} option: ${opt}"
        return
    fi
    _message "${mode} option value"
    guard=${guard#*:}
    case ${guard} in
        ('') ;;
        (MSG:*)
            _message ${guard#*:}
            ;;
        (DESC:*)
            eval "desc=( ${guard#*:} )"
            _describe -t "tmux-${mode}-option-value" "${opt}" desc
            ;;
        (*)
            eval ${guard}
            ;;
    esac
}

function __tmux-session-options() {
    local -a tmux_session_options
    tmux_session_options=(
        'assume-paste-time:assume keys are pasted instead of typed if this fast'
        'base-index:define where to start numbering'
        'bell-action:set action on window bell'
        'bell-on-alert:ring the terminal bell when an alert occurs'
        'default-command:default command for new windows'
        'default-shell:default shell executable'
        'destroy-unattached:destroy session if no client is attached'
        'detach-on-destroy:detach client if attached session is destroyed'
        'display-panes-colour:colour used for display-panes'
        'display-panes-active-colour:colour for active pane in display-panes'
        'display-panes-time:time (in msecs) of display-panes output'
        'display-time:time (in msecs) messages are displayed'
        'history-limit:number of copy-mode lines per window'
        'key-table:default key table'
        'lock-after-time:lock sessions after N seconds'
        'lock-command:command to run for locking a client'
        'message-command-style:status line message command style'
        'message-style:status line message style'
        'mouse:enable mouse support'
        'prefix:primary prefix key'
        'prefix2:secondary prefix key'
        'renumber-windows:renumber windows if a window is closed'
        'repeat-time:time for multiple commands without prefix-key presses'
        'set-titles:try to set xterm window titles'
        'set-titles-string:format used by set-titles'
        'status:show or hide the status bar'
        'status-interval:interval (in seconds) for status bar updates'
        'status-justify:position of the window list in status bar'
        'status-keys:mode to use in status bar modes (vi/emacs)'
        'status-left:format to use left in status bar'
        'status-left-length:maximum length of the left part of the status bar'
        'status-left-style:style of left part of status line'
        'status-position:status line position'
        'status-right:format to use right in status bar'
        'status-right-length:maximum length of the right part of the status bar'
        'status-right-style:style of right part of status line'
        'status-style:style status line'
        "update-environment:list of variables to be copied to a session's environment"
        'visual-activity:display status line messages upon activity'
        'visual-bell:use visual bell instead of audible'
        'visual-silence:print a message if monitor-silence is on'
        'word-separators:string of characters considered word separators'
    )
    _describe -t tmux-options 'tmux session option' tmux_session_options
}

function __tmux-options-complete() {
    local mode="$1" state="$2"

    case ${state} in
        name_or_value)
            if (( CURRENT == 1 )) && [[ ${mode} == 'session' ]]; then
                __tmux-session-options
            elif (( CURRENT == 1 )) && [[ ${mode} == 'server' ]]; then
                __tmux-server-options
            elif (( CURRENT == 1 )) && [[ ${mode} == 'window' ]]; then
                __tmux-window-options
            elif (( CURRENT == 2 )); then
                __tmux-option-guard ${mode} ${words[1]}
            else
                __tmux-nothing-else
            fi
            ;;
    esac
}

function __tmux-panes() {
    local expl line
    local -i num
    local -a panes opts

    compset -P '*.'
    if [[ -n ${IPREFIX} ]]; then
        opts=( -t "${IPREFIX%.}" )
    else
        opts=( )
    fi
    num=0
    command tmux 2> /dev/null list-panes "${opts[@]}" | while IFS= read -r line; do
        panes+=( $(( num++ )):${line//:/} )
    done
    _describe -t panes 'panes' panes "$@"
    if [[ ${IPREFIX} != *. ]]; then
        _wanted windows expl 'windows' __tmux-windows -S.
    fi
}

function __tmux-server-options() {
    local -a tmux_server_options
    tmux_server_options=(
        'buffer-limit:number of buffers kept per session'
        'default-terminal:default terminal definition string'
        'escape-time:set timeout to detect single escape characters (in msecs)'
        'exit-unattached:make server exit if it has no attached clients'
        'focus-events:request focus events from terminal'
        'history-file:tmux command history file name'
        'message-limit:set size of message log per client'
        'quiet:enable/disable the display of various informational messages'
        'set-clipboard:use esc sequences to set terminal clipboard'
        'terminal-overrides:override terminal descriptions'
    )
    _describe -t tmux-server-options 'tmux server option' tmux_server_options
}

function __tmux-sessions() {
    local -a sessions
    sessions=( ${${(f)"$(command tmux 2> /dev/null list-sessions)"}/:[ $'\t']##/:} )
    _describe -t sessions 'sessions' sessions "$@"
}

function __tmux-sessions-attached() {
    local -a sessions
    sessions=( ${${(f)"$(command tmux 2> /dev/null list-sessions)"}/:[ $'\t']##/:} )
    sessions=( ${(M)sessions:#*"(attached)"} )
    _describe -t sessions 'attached sessions' sessions "$@"
}

# Complete attached-sessions and detached-sessions as separate tags.
function __tmux-sessions-separately() {
    local ret=1
    local -a sessions detached_sessions attached_sessions
    sessions=( ${${(f)"$(command tmux 2> /dev/null list-sessions)"}/:[ $'\t']##/:} )
    detached_sessions=(    ${sessions:#*"(attached)"} )
    attached_sessions=( ${(M)sessions:#*"(attached)"} )

    # ### This seems to work without a _tags loop but not with it.  I suspect
    # ### that has something to do with _describe doing its own _tags loop.
    _tags detached-sessions attached-sessions
    # Placing detached before attached means the default behaviour of this
    # function better suits its only current caller, _tmux-attach-session().
    _requested detached-sessions && _describe -t detached-sessions 'detached sessions' detached_sessions "$@" && ret=0
    _requested attached-sessions && _describe -t attached-sessions 'attached sessions' attached_sessions "$@" && ret=0

    return ret
}

function __tmux-socket-name() {
    local expl sdir
    local curcontext="${curcontext}"
    local -a socks
    zstyle -s ":completion:${curcontext}:sockets" socketdir sdir || sdir="${TMUX_TMPDIR:-/tmp}/tmux-${UID}"
    socks=(${sdir}/*(=:t))
    _wanted socket expl 'socket name' compadd ${expl} -- ${socks}
}

function __tmux-style() {
    _message 'not implemented yet'
}

function __tmux-window-options() {
    local -a tmux_window_options
    tmux_window_options=(
        'aggressive-resize:aggressively resize windows'
        'allow-rename:allow programs to change window titles'
        'alternate-screen:allow alternate screen feature to be used'
        'automatic-rename:attempt to automatically rename windows'
        'automatic-rename-format:format for automatic renames'
        'clock-mode-colour:set clock colour'
        'clock-mode-style:set clock hour format (12/24)'
        'force-height:force a windows to a certain height'
        'force-width:force a windows to a certain width'
        'main-pane-height:set height for main-* layouts'
        'main-pane-width:set width for main-* layouts'
        'mode-keys:mode to use in copy and choice modes (vi/emacs)'
        'mode-style:set window modes style'
        'monitor-activity:monitor window activity'
        'monitor-silence:monitor window for inactivity'
        'other-pane-height:height of other panes'
        'other-pane-width:width of other panes'
        'pane-active-border-style:style of border of active pane'
        'pane-base-index:integer at which to start indexing panes'
        'pane-border-format:set pane border format string'
        'pane-border-status:turn border status off or set its position'
        'pane-border-style:style of border pane'
        "remain-on-exit:don't destroy windows after the program exits"
        'synchronize-panes:send input to all panes of a window'
        'window-active-style:style of active window'
        'window-status-activity-style:style of status bar activity tag'
        'window-status-bell-style:style of status bar bell tag'
        'window-status-current-format:set status line format for active window'
        'window-status-current-style:style of current window in status bar'
        'window-status-format:set status line format for all but the active window'
        'window-status-last-style:style of last window in status bar'
        'window-status-separator:separator drawn between windows in status line'
        'window-status-style:general status bar style'
        'window-style:style of window'
        'wrap-search:search wrap around at the end of a pane'
        'xterm-keys:generate xterm-style function key sequences'
    )
    _describe -t tmux-window-options 'tmux window option' tmux_window_options
}

function __tmux-windows() {
    local expl
    local -a wins opts

    compset -P '*:'
    if [[ -n ${IPREFIX} ]]; then
        opts=( -t "${IPREFIX%:}" )
    else
        opts=( )
    fi
    wins=( ${${(M)${(f)"$(command tmux 2> /dev/null list-windows "${opts[@]}")"}:#<->*}/:[ $'\t']##/:} )
    _describe -t windows 'windows' wins "$@"
    if [[ ${IPREFIX} != *: ]]; then
        _wanted sessions expl 'sessions' __tmux-sessions -S:
    fi
}

# And here is the actual _tmux(), that puts it all together:
_tmux() {
  local curcontext="${curcontext}" state line ret=1
  local mode
  local tmuxcommand
  local tmux_describe

  _arguments -C -s -w \
    '-2[force using 256 colours]' \
    '-c[execute a shell command]:command name:_command_names' \
    '-C[start tmux in control mode. -CC disables echo]' \
    '-f[specify configuration file]:tmux config file:_files -g "*(-.)"' \
    '-l[behave like a login shell]' \
    '-L[specify socket name]:socket name:__tmux-socket-name' \
    '-S[specify socket path]:server socket:_path_files -g "*(=,/)"' \
    '-u[force using UTF-8]' \
    '-v[request verbose logging]' \
    '-V[report tmux version]' \
    '*:: :->subcommand_or_options' && ret=0

  [[ -z $state ]] && return ret

  if (( CURRENT == 1 )); then
    zstyle -s ":completion:${curcontext}:subcommands" mode mode || mode='both'
    if [[ ${mode} == 'commands' ]]; then
      _describe -t subcommands 'tmux commands' _tmux_commands && ret=0
    elif [[ ${mode} == 'aliases' ]]; then
      _describe -t subcommands 'tmux aliases' _tmux_aliases && ret=0
    else
      _describe -t subcommands 'tmux commands and aliases' _tmux_commands -- _tmux_aliases && ret=0
    fi
  else
    tmuxcommand="${words[1]}"
    if [[ -n ${_tmux_aliasmap[$tmuxcommand]} ]] ; then
      tmuxcommand="${_tmux_aliasmap[$tmuxcommand]}"
    fi
    if ! (( ${+functions[_tmux-$tmuxcommand]} )); then
      local low high
      low=$_tmux_commands[(i)$tmuxcommand*]
      high=$_tmux_commands[(I)$tmuxcommand*]
      if (( low == high )); then
	tmuxcommand=${_tmux_commands[low]%%:*}
      elif (( low < high )); then
	_message "ambiguous command $tmuxcommand"
      else
	_message "subcommand $tmuxcommand not known"
	_normal && ret=0
      fi
    fi
    curcontext="${curcontext%:*}-${tmuxcommand}:"
    _call_function ret _tmux-${tmuxcommand}
  fi
  return ret
}

# description generation follows; only done on 1st _tmux call.
local f desc
local -A rev
local tmux_describe
tmux_describe='yes, please'
for f in ${(k)_tmux_aliasmap} ; do
  rev+=( ${_tmux_aliasmap[$f]} $f )
done
for f in ${(M)${(k)functions}:#_tmux-*} ; do
  desc="$($f)"
  _tmux_commands+=( "${f#_tmux-}${desc:+:$desc}" )
  [[ -n ${rev[${f#_tmux-}]} ]] && _tmux_aliases+=( "${rev[${f#_tmux-}]}${desc:+:$desc}" )
done

_tmux "$@"