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/zsh-newuser-install
# Function to install startup files for a new user.
# Currently it only creates or edits .zshrc.
#
# It can be run again by giving it the option "-f".

# Sanitize environment.
emulate -L zsh
setopt extendedglob nonomatch warncreateglobal

# How the function will be referred to.
local myname=zsh-newuser-install

# Quick test not requiring any setting up.
# Don't run if we're root.  (These variables are provided by the shell.)
if (( EUID == 0 || UID == 0 )); then
  if [[ $1 = -f ]]; then
    print -r "$myname: won't run as root.  Read the manual." >&2
  fi
  return 1
fi

# clear is missing in some Cygwin configurations (lacking ncurses)
if ! ( clear >/dev/null 2>/dev/null ); then
  if zmodload zsh/termcap 2>/dev/null; then
    clear() { echotc cl; }
  else
    clear() { print -n "\e[H\e[J"; }
  fi
fi

# The directory in which to look for and save .zshrc.
local zd=${ZDOTDIR:-$HOME}
# The same directory in a user friendly form, i.e. with ~ replacement.
# (We don't want to use glob_subst since that has other side effects.)
local zdmsg
# The message used if an other blank .zshrc is created.
local msg="# Created by newuser for $ZSH_VERSION"
# The lines marking the start and end of the section edited.
local startline="# Lines configured by $myname"
local endline="# End of lines configured by $myname"
# Prompts used for reading a key.  The initial "?" is required.
local shortprompt="?--- Type a key --- "
local longprompt="?--- Type one of the keys in parentheses --- "
# Prefix for all temporary files.  Any files starting with this
# will be removed at the end of the script.
local tmpfile=${TMPPREFIX:-/tmp/zsh}-zni-$$
# Report of the state of settings for the top-level menu.
local -A install_state
# Values of all parameters etc. to be saved (including
# those read in from the existing file.)
local -A parsed_parameters parsed_options parsed_bindings parsed_keymaps
# Corresponding state in a user-readable form.
local -A state_parameters state_options state_bindings state_keymaps
# Indicate whether an option defaults on or off.
local -A default_options
# Lines read in from between $startline and $endline which were
# not understood.  These are retained but moved out of that section
# with a message.
local -a unparsed
# Lines used in submenus: the setting to output in a form
# that can be exeucuted (an assignment, setopt or unsetopt), a brief message
# about the setting, and the state copied from and to state_parameters or
# state_options.  Elements of all three arrays must correspond.
local -a output_lines display_lines state_lines
# Variable indicating some of the lines in the above variables
# have been read in, i.e. the user has already configured the
# particular set of settings.
integer lines_read
# Lines to set up completion.  This is special as it is only
# edited by compinstall, not this function.
local -a completion_lines
# Utility variables
local -a reply match mbegin mend
# Key read from user, used all over the place.
local key
# For default replies from read
local REPLY
integer save lines_found

install_state[history]=Recommended
install_state[completion]=Recommended
install_state[bindkey]=Recommended

# Don't save anything if interrupted.
trap 'save=0' HUP INT QUIT

# Substitute an initial ~ for human consumption.
if [[ $zd = $HOME(#b)(|/*) ]]; then
  zdmsg="~$match[1]"
else
  zdmsg=$zd
fi

# Don't run if we can't write to $zd.
# Assume this is a temporary condition and exit silently---
# if this really is a new user this probably isn't the right
# time for screeds of explanation.
if [[ ! -w $zd ]]; then
  if [[ $1 = -f ]]; then
    print -r "$myname: can't write to $zdmsg." >&2
  fi
  return 1
fi

# Don't run unless we can talk to the user.
if [[ ! -t 0 || ! -t 1 ]]; then
  if [[ $1 = -f ]]; then
    print -r "$myname: can only be used interactively." >&2
  fi
  return 1
fi

# Don't run unless terminal is sane.
if (( ${LINES:-0} < 15 || ${COLUMNS:-0} < 72 )); then
  return 1
fi

if [[ $1 != -f ]]; then
  # The zsh/newuser module already tests for the following, so this test only
  # triggers if zsh-newuser-install is run by hand.
  if [[ -e $zd/.zshenv || -e $zd/.zprofile || \
        -e $zd/.zshrc || -e $zd/.zlogin ]]; then
    print -r "$myname:  startup files exist, aborting.

Use the argument -f if you want to force the function to be run again." >&2
    return 1
  fi
fi

# start of try block for tidy-up in always block
{

########################################################################
# Utility functions
########################################################################

# All internal functions start with __zni_.  These will be removed
# when the main function exits.

# Read existing lines from .zshrc, if any.
__zni_retrieve_lines() {
  local line

  reply=()

  lines_found=0

  [[ -f $zd/.zshrc ]] || return 1

  grep "$startline" $zd/.zshrc 1>/dev/null 2>&1 || return 1

  lines_found=1

  sed -n "/^[	]*$startline/,/^[	]*$endline/p" $zd/.zshrc |
  while read -r line; do
    reply+=($line)
  done

  return 0
}


# First argument is a state; other arguments are lines
# to parse.  They should either contain single assignments or
# setopt or unsetopt statements.  The state for each parameter
# or option so parsed is set to the value given by the first argument.
__zni_parse_lines() {
  local line opt warned first
  local -a args
  local state=$1

  shift

  for line in "$@"; do
    case $line in
      ((#b)[[:blank:]]#([[:IDENT:]]##)=(*))
      parsed_parameters[$match[1]]=$match[2]
      state_parameters[$match[1]]=$state
      ;;

      ((#b)[[:blank:]]#(un|)setopt[[:blank:]]##(*))
      # TBD: handle setopt noX / unsetopt X
      for opt in ${=match[2]}; do
	opt=${${opt//(#m)[[:upper:]]/${(L)MATCH}}//_}
	if [[ $match[1] = un ]]; then
	  parsed_options[$opt]=off
	else
	  parsed_options[$opt]=on
	fi
	state_options[$opt]=$state
      done
      ;;

      ((#b)[[:blank:]]#bindkey[[:blank:]]##(*))
      args=(${(z)match[1]})
      # store keys unquoted: will need quoting for output.
      first=${(Q)args[1]}
      shift args
      if [[ $first = -[ev] && ${#args} -eq 0 ]]; then
	case $first in
	  (-e)
	  parsed_keymaps[main]=emacs
	  ;;

	  (-v)
	  parsed_keymaps[main]=vi
	  ;;
	esac
	state_keymaps[main]=$state
      else
	# TODO: handling keymap options
	parsed_bindings[first]=${args[2,-1]}
	state_bindings[first]=$state
      fi
      ;;

      ([[:blank:]]#($startline|$endline|))
      ;;

      (*)
      unparsed+=($line)
      print -r "WARNING: failed to understand line:
  $line
which will be retained but not edited."
      warned=1
      ;;
    esac
  done

  if [[ -n $warned ]]; then
    read -k key$shortprompt
  fi
}

# Apply defaults.  Arguments in the form
#   -p parameter_name default_value description
#      ...
#   -o option_name default=on|off description
#      ...
# Options on by default should begin !, e.g. !nomatch.  They
# will still appear under the base option but with an indication that
# the default is on.  The default applies to the base option.  Hack, sorry.
#   -b bindkey_string default_value description
#      ...
#   -B default_keymap=emacs|vi|none description
#
# They're not really defaults (they're not the same as the
# builtin defaults), so the description output is "not yet saved".
#
# All variables to be edited in this section must be mentioned,
# though defaults can be blank in which case nothing will be
# saved unless the variable is set by the user.  The description
# is then "no value set".
#
# -B is a bit strange: it's simply designed to allow the user to
# select "bindkey -e" for Emacs or "bindkey -v" for vi.  It only
# takes a single argument.  Real key bindings use -b.
#
# This operation transfers some subset of settings from the parsed_*
# and state_* variables to the *_lines variables for editing.
__zni_apply_defaults() {
  local un suf

  # Reset the lines to be edited.
  state_lines=()
  display_lines=()
  output_lines=()
  lines_read=0

  case $1 in
    (-p)
    shift
    while [[ $# -gt 0 && $1 != -* ]]; do
      # skip default if it was read in
      if [[ -z $state_parameters[$1] ]]; then
	parsed_parameters[$1]=$2
	if [[ -n $2 ]]; then
	  state_parameters[$1]="not yet saved"
	else
	  state_parameters[$1]="no value set"
	fi
      elif [[ $state_parameters[$1] = saved ]]; then
	(( lines_read++ ))
      fi
      state_lines+=($state_parameters[$1])
      display_lines+=("$3")
      output_lines+=("$1=$parsed_parameters[$1]")

      shift 3
    done
    ;;

    (-o)
    shift
    while [[ $# -gt 0 && $1 != -* ]]; do
      # skip default if there was a setting
      if [[ $1 != ${1##!} ]]; then
	argv[1]=${1##!}
	default_options[$1]=on
      else
	default_options[$1]=off
      fi
      if [[ -z $state_options[$1] ]]; then
	parsed_options[$1]=$2
	if [[ -n $2 ]]; then
	  state_options[$1]="not yet saved"
	else
	  state_options[$1]="no value set"
	fi
      elif [[ $state_options[$1] = saved ]]; then
	(( lines_read++ ))
      fi
      if [[ $parsed_options[$1] = on ]]; then
	un=
	suf=
      elif [[ -z $parsed_options[$1] && $default_options[$1] = on ]]
      then
	un=
	suf=", default on"
      else
	# display as unsetopt even if no value to save yet
	un=un
	suf=
      fi
      state_lines+=("$state_options[$1]$suf")
      display_lines+=("$3")
      output_lines+=("${un}setopt $1")

      shift 3
    done
    ;;

    (-b)
    shift
    # this will barf on bindings beginning -; there's no good
    # reason to rebind that, even in vi command mode, so perhaps
    # we just add it to the sanity checks when we get around to them.
    while [[ $# -gt 0 && $1 != -* ]]; do
      if [[ -z $state_bindings[$1] ]]; then
	parsed_bindings[$1]=$2
	if [[ -n $2 ]]; then
	  state_bindings[$1]="not yet saved"
	else
	  state_bindings[$1]="no value set"
	fi
      elif [[ $state_bindings[$1] = saved ]]; then
	(( lines_read++ ))
      fi
      state_lines+=($state_bindings[$1])
      display_lines+=("$3")
      output_lines+=("bindkey ${(qq)1}${2:+ $2}")

      shift 3
    done
    ;;

    (-B)
    shift
    if [[ -z $state_keymaps[main] ]]; then
      parsed_keymaps[main]=$1
      if [[ $1 = none ]]; then
	state_keymaps[main]="no value set"
      else
	state_keymaps[main]="not yet saved"
      fi
    elif [[ $state_keymaps[main] = saved ]]; then
      (( lines_read++ ))
    fi
    state_lines+=($state_keymaps[main])
    display_lines+=("$2")
    # display as -e even if no value to save yet
    if [[ $parsed_keymaps[main] = vi ]]; then
      output_lines+=("bindkey -v")
    else
      output_lines+=("bindkey -e")
    fi

    shift 2
    ;;
  esac
}


# Display and edit the settings given by the set of *_lines arrays.
# If requested by the user, apply the settings, updating the
# parsed_* and state_* variables.
__zni_display_and_edit() {
  integer i changes
  local default edval ldisp rdisp
  local -a states displays outputs tstval

  states=("${state_lines[@]}")
  displays=("${display_lines[@]}")
  outputs=("${output_lines[@]}")

  if [[ -n ${states[(r)not yet saved]} ]]; then
    # default should be installed, unless user says otherwise
    (( changes++ ))
  fi

  while true; do
    clear
    print -r $1
    # snicker...
    print -r ${(l.${#1}..=.):-}
    print
    if (( $# > 1 )); then
      print -rl $argv[2,-1]
      print
    fi

    # Output each setting with a description and state.
    for (( i = 1; i <= ${#output_lines}; i++ )); do
      default=${states[$i]%%,*}
      if [[ $default = ("no value set"|"not to be saved"*) ]]; then
	ldisp="# $outputs[$i]"
      else
	ldisp=$outputs[$i]
      fi
      rdisp=${default:+($default)}
      print -r "# ($i) $displays[$i]
$ldisp${(l.$COLUMNS-${#ldisp}-${#rdisp}-1.):-}$rdisp"
    done

    if (( changes )); then
      print -r "
# (0)  Remember edits and return to main menu (does not save file yet)
# (q)  Abandon edits and return to main menu
"
    else
      print -r "
# (0) or (q)  Return to main menu (no changes made yet)
"
    fi
    read -k key$longprompt
    print

    if [[ $key = <-> && $key -ge 1 && $key -le ${#outputs} ]]; then
      (( i = key ))
      case $outputs[$i] in
	((#b)(|un)setopt' '(*))
	# Try to locate the appropriate section in the manual.
	# I personally have no wish whatsoever to make this
	# use sed or awk.  Suggestions welcome.
	if [[ -s $tmpfile-man-options ]]; then
	  perl -ne 's/^(\s*)([A-Z]+)_?([A-Z]*)_?([A-Z]*)(\s*\(.+\)|\s*\<.+\>)*\s*$/\L$1$2$3$4\n/ and "'$match[2]'" =~ /^(|no)\L$2$3$4$/ and $print = 1 and next; next unless $print; exit if /^\s*$/; print; ' <$tmpfile-man-options >$tmpfile-man 2>/dev/null
	else
	  rm -f $tmpfile-man
	fi
	while true; do
	  clear
	  if [[ -s $tmpfile-man ]]; then
	    read <$tmpfile-man
	    print "Option $match[2]:"
	    cat $tmpfile-man
	    print
	  else
	    print "Option $match[2]:  $displays[$i]"
	  fi
	  print "The option $match[2] is currently ${match[1]:+un}set.
Type:
  (s) to set it (turn it on)
  (u) to unset it (turn it off)
  (n) neither to set or unset it (use shell default: \
$default_options[$match[2]])
  (k) or (q) to keep the current setting:"
	  read -k key$shortprompt
	  print

	  case $key in
	    (s)
	    (( changes++ ))
	    outputs[$i]="setopt $match[2]"
	    states[$i]="set but not saved"
	    ;;

	    (u)
	    (( changes++ ))
	    outputs[$i]="unsetopt $match[2]"
	    states[$i]="set but not saved"
	    ;;

	    (n)
	    (( changes++ ))
	    outputs[$i]="unsetopt $match[2]"
	    states[$i]="no value set"
	    ;;

	    ([kq])
	    ;;

	    (*)
	    continue
	    ;;
	  esac
	  break;
	done
	;;

	((#b)([^=]##)=(*))
	if [[ -s $tmpfile-man-param ]]; then
	  perl -ne 's/^(\s*)([A-Z]+)(\s*\<.+\>)*\s*$/$1$2\n/ and "$2" eq "'$match[1]'" and $print = 1; next unless $print; exit if /^\s*$/; print;' <$tmpfile-man-param >$tmpfile-man 2>/dev/null
	else
	  rm -f $tmpfile-man
        fi
	if [[ -s $tmpfile-man ]]; then
	  print -n Variable
	  cat $tmpfile-man
	  print
	else
	  print -r "Variable ${match[1]}:  $displays[$i]"
	fi
	print -r "Edit a value.  If it is left blank, nothing will be saved:"
	edval=$match[2]
	if vared -M emacs -p "$match[1]> " -h edval; then
	  # check this assignment doesn't produce multiple words
	  # e.g. "HISTFILE=never rm -f ~" does produce multiple words...
	  # this isn't perfect, e.g. "(this would get split on assignment)",
	  # but that's fairly benign.
	  tstval=(${=edval})
	  if (( ${#tstval} > 1 )); then
	    print "Error: value isn't a single word.
Use quotes or backslashes if your value contains spaces.
Note that you shouldn't quote an initial ~ in file names." >&2
	    read -k key$shortprompt
	    # now check the assignment works...
	    # don't suppress any errors, they may be useful.
	    # this means we need to suppress warncreateglobal.
	  elif ! ( typeset -g $match[1]; eval "$match[1]=$edval" ); then
	    print "Error: bad shell syntax in value.
The value will be assigned to the variable exactly as you enter it.
Make sure all quotes are paired." >&2
	    read -k key$shortprompt
	  else
	    outputs[$i]="$match[1]=$edval"
	    if [[ -n $edval ]]; then
	      states[$i]="set but not saved"
	    else
	      states[$i]="no value set"
	    fi
	    (( changes++ ))
	  fi
	else
	  read -k key'?--- Edit abandoned, type a key --- '
	fi
	;;

	(bindkey' '-[ev])
	while true; do
	  print -nr "Pick a keymap (set of keys) to use when editing.
Type:
  (e) for Emacs keymap (recommended unless you are vi user)
  (v) for Vi keymap
  (n) not to set a keymap (allow shell to choose)
  (k) to keep the current setting, "
	  if [[ ${state_lines[$i]%%,*} = ("no value set"|"not to be saved") ]]
	  then
	    print -r "(n):"
	  elif [[ $output_lines[$i] = *-v ]]; then
	    print -r "(v):"
	  else
	    print -r "(e):"
	  fi
	  read -k key$longprompt
	  case $key in
	    (e)
	    (( changes++ ))
	    outputs[$i]="bindkey -e"
	    states[$i]="set but not saved"
	    ;;

	    (v)
	    (( changes++ ))
	    outputs[$i]="bindkey -v"
	    states[$i]="set but not saved"
	    ;;

	    (n)
	    (( changes++ ))
	    outputs[$i]="bindkey -e"
	    states[$i]="not to be saved"
	    ;;

	    (k)
	    ;;

	    (*)
	    continue
	    ;;
	  esac
	  break
	done
	;;

	(bindkey' '*)
	# TODO: this needs writing.  We need to be able to read
	# keys and translate them, sanity check them, and ideally
	# handle keymaps, at least vi command and insert.
	;;

	(*)
	print "*** Internal error: bad setting '$outputs[$i]' ***" >&2
	read -k key'?--- Type a key in forlorn hope --- '
	;;
      esac
    elif [[ $key = 0 ]]; then
      # Update the *_lines variables
      state_lines=("${states[@]}")
      display_lines=("${displays[@]}")
      output_lines=("${outputs[@]}")

      # Also save any lines suitably marked to parsed_* and state_*
      # by rerunning __zni_parse_lines on each such line.
      for (( i = 1; i <= ${#output_lines}; i++ )); do
	if [[ ${state_lines[$i]%%,*} = \
	  ("set but not saved"|"not to be saved"|"not yet saved") ]]
	then
	  __zni_parse_lines ${state_lines[$i]%%,*} $output_lines[$i]
	fi
      done

      return $(( changes == 0 ))
    elif [[ $key = [qQ] ]]; then
      return 1
    fi
  done
}


# Print and despatch a submenu.
# The first argument is the title.  The remaining arguments
# are pairs of descriptions and functions to execute.
# There shouldn't be more than 9 entries.
# The usual entries 0 and q are added automatically.
__zni_submenu() {
  local title=$1
  local desc func
  local -a descs funcs
  integer i

  shift

  clear
  print -r $title
  print -r ${(l.${#title}..=.):-}

  for desc func; do
    if [[ -z $func ]]; then
      print "*** Internal error: bad argument set for __zni_submenu ***" >&2
      read -k key'?--- Type a key in forlorn hope --- '
      return 1
    fi

    descs+=($desc)
    funcs+=($func)
  done

  while true; do
    for (( i = 1; i <= ${#descs}; i++ )); do
      print -r "
($i)  $descs[$i]"
    done
    print -r "
(0) or (q)  Return to previous menu"

    read -k key$longprompt

    if [[ $key = [0qQ] ]]; then
      return 1
    elif (( key >= 1 && key <= ${#funcs} )); then
      $funcs[$key]
    fi
  done
}


# Save all values that have been edited to .zshrc.
__zni_save() {
  local key optline newline
  local -a on_opts off_opts lines lines2
  integer i

  # Record lines containing parameter settings, sorted.
  for key in ${(ok)parsed_parameters}; do
    if [[ $state_parameters[$key] != ("no value set"|"not to be saved") ]]
    then
      lines+=("$key=$parsed_parameters[$key]")
    fi
  done

  # Search through sorted options, make list of those to
  # be turned on and off.  Those marked "no value set" aren't
  # to be output.
  for key in ${(ok)parsed_options}; do
    if [[ $state_options[$key] != ("no value set"|"not to be saved") ]]; then
      if [[ $parsed_options[$key] = on ]]; then
	on_opts+=($key)
      else
	off_opts+=($key)
      fi
    fi
  done

  # Construct lines of options to turn on, keeping them short.
  optline="setopt"
  for (( i = 1; i <= ${#on_opts}; i++ )); do
    newline="$optline $on_opts[$i]"
    if [[ ${#newline} -ge 72 ]]; then
      lines+=($optline)
      optline="setopt $on_opts[$i]"
    else
      optline=$newline
    fi
    if (( i == ${#on_opts} )); then
      lines+=($optline)
    fi
  done

  # Construct lines of options to turn off, keeping them short.
  optline="unsetopt"
  for (( i = 1; i <= ${#off_opts}; i++ )); do
    newline="$optline $off_opts[$i]"
    if [[ ${#newline} -ge 72 ]]; then
      lines+=($optline)
      optline="unsetopt $off_opts[$i]"
    else
      optline=$newline
    fi
    if (( i == ${#off_opts} )); then
      lines+=($optline)
    fi
  done

  # Construct lines of bindkey commands.  First the keymap.
  if [[ $state_keymaps[main] != (|"no value set"|"not to be saved") ]]; then
    case $parsed_keymaps[main] in
      (emacs)
      lines+=("bindkey -e")
      ;;

      (vi)
      lines+=("bindkey -v")
      ;;

      (none)
      ;;

      (*)
      print -r "\
*** Internal error: bad type $parsed_keymaps[main] for keymap ***" >&2
      read -k key'?--- Type a key in forlorn hope --- '
      ;;
    esac
  fi
  # Now bindings.
  for key in ${(ok)parsed_bindings}; do
    if [[ $state_bindings[$key] != ("no value set"|"not to be saved") ]]; then
      lines+=("bindkey ${(qq)key} ${parsed_bindings[$key]}")
    fi
  done

  # Save the lines with a start and end marker to a temporary file.
  print -rl $startline $lines $endline >$tmpfile

  if (( ${#unparsed} )); then
    print "# The following lines were read by $myname.
# They were moved here as they could not be understood.
# $(date)
${(F)unparsed}
# End of lines moved by $myname." >>$tmpfile
  fi

  if grep "$startline"  $zd/.zshrc 1>/dev/null 2>&1; then
    # Found the start line; replace the section.
    # We could this by reading the lines in zsh, but in case
    # the .zshrc is huge it's perhaps better to use sed.
    sed -e "/^[		]*$endline/r $tmpfile
/^[	]*$startline/,/^[	]*$endline/d" $zd/.zshrc >${tmpfile}.repl &&
    cp ${tmpfile}.repl $zd/.zshrc
  else
    # No current start marker; just append.
    cat $tmpfile >>$zd/.zshrc
  fi
}


########################################################################
# Specific configurations
########################################################################

__zni_history_config() {
  __zni_apply_defaults -p \
    HISTSIZE 1000 "Number of lines of history kept within the shell." \
    HISTFILE $zdmsg/.histfile "File where history is saved." \
    SAVEHIST 1000 "Number of lines of history to save to \$HISTFILE."

  if __zni_display_and_edit "History configuration"; then
    install_state[history]="Unsaved changes"
    save=1
  fi
}


__zni_completion_config() {
  autoload -Uz compinstall
  if compinstall -d; then
    print "The completion system has already been activated.
You can run the configuration tool (compinstall) at any time by typing
   autoload -Uz compinstall
   compinstall
Do you wish to run it now [y/n]?"
    read -k key$shortprompt
    if [[ $key = [yY] ]]; then
      compinstall
    fi
    print
  else
    while true; do
      clear
      print "The new completion system (compsys) allows you to complete
commands, arguments and special shell syntax such as variables.  It provides
completions for a wide range of commonly used commands in most cases simply
by typing the TAB key.  Documentation is in the zshcompsys manual page.
If it is not turned on, only a few simple completions such as filenames
are available but the time to start the shell is slightly shorter.

You can:
  (1)  Turn on completion with the default options.

  (2)  Run the configuration tool (compinstall).  You can also run
       this from the command line with the following commands:
        autoload -Uz compinstall
        compinstall
       if you don't want to configure completion now.

  (0)  Don't turn on completion.
"
      read -k key$longprompt
      case $key in
	(1)
	completion_lines=${(f)"$(compinstall -o)"}
	install_state[completion]="Unsaved changes"
	save=1
	;;

	(2)
	if compinstall; then
	  install_state[completion]="Configured"
	  # compinstall has done it's thing, so we don't need
	  # to write anything.
	  completion_lines=()
	fi
	;;

	(0)
	completion_lines=()
	install_state[completion]="Recommended"
	;;

	(*)
	continue
	;;
      esac
      break
    done
  fi
}

__zni_bindkey_config() {
  __zni_apply_defaults -B emacs "Change default editing configuration"

  if __zni_display_and_edit "Default editing configuration" \
    "The keys in the shell's line editor can be made to behave either" \
    "like Emacs or like Vi, two common Unix editors.  If you have no" \
    "experience of either, Emacs is recommended.  If you don't pick one," \
    "the shell will try to guess based on the EDITOR environment variable." \
    "Usually it's better to pick one explicitly."; then
    install_state[bindkey]="Unsaved changes"
    save=1
  fi
}

__zni_completion_save() {
  if (( ${#completion_lines} )); then
    # We don't try to replace existing lines of completion configuration ---
    # that's up to compinstall.  We should already have tested that
    # there was no existing completion set up.
    print -rl $completion_lines >>$zd/.zshrc
  fi
}


__zni_options_config() {
  # when we have enough, should use:
  #   __zni_submenu "Common shell options"

  # This is deliberately just a tiny selection.
  # Feel free to extend it, but if you do, consider using __zni_submenu.
  # The "no" prefix is used to indicate options on by default.
  __zni_apply_defaults -o autocd '' "Change directory given just path." \
    extendedglob '' "Use additional pattern matching features." \
    appendhistory '' "Append new history lines instead of overwriting." \
    '!nomatch' '' "Unmatched patterns cause an error." \
    '!beep' '' "Beep on errors." \
    notify '' "Immediately report changes in background job status."

  if __zni_display_and_edit "Common shell options" \
  "The following are some of the shell options that are most often used." \
  "The descriptions are very brief; if you would like more information," \
  "read the zshoptions manual page (type \"man zshoptions\")."; then
    install_state[options]="Unsaved changes"
    save=1
  fi
}


########################################################################
# Main function
########################################################################

# Read and parse any existing lines, in case the function
# was called again.
__zni_retrieve_lines &&
  __zni_parse_lines saved "$reply[@]"

if [[ $state_parameters[HISTORY] = saved ]]; then
  install_state[history]="Saved"
fi
autoload -Uz compinstall
zstyle :compinstall filename $zd/.zshrc
if compinstall -d; then
  install_state[completion]="Saved"
fi


# skip initial screen if the function was deliberately run by the user.
if [[ $1 != -f ]]; then
  clear
  print -r "This is the Z Shell configuration function for new users,
$myname.
You are seeing this message because you have no zsh startup files
(the files .zshenv, .zprofile, .zshrc, .zlogin in the directory
$zdmsg).  This function can help you with a few settings that should
make your use of the shell easier.

You can:

(q)  Quit and do nothing.  The function will be run again next time."
  if [[ ! -f $zd/.zshrc ]]; then
    print -r "
(0)  Exit, creating the file $zdmsg/.zshrc containing just a comment.
     That will prevent this function being run again."
  fi
  print -r "
(1)  Continue to the main menu.
"
  if [[ -f /etc/zsh/newuser.zshrc.recommended ]]; then
    print -r "(2)  Populate your $zdmsg/.zshrc with the configuration recommended
     by the system administrator and exit (you will need to edit
     the file by hand, if so desired).
"
  fi

  read -k key$longprompt
  print

  case $key in
    ([qQ])
    return 0
    ;;

    (0)
    print -r $msg >$zd/.zshrc
    return 0
    ;;

    (1)
    ;;

    (2)
    cp /etc/zsh/newuser.zshrc.recommended $zd/.zshrc
    source $zd/.zshrc
    return 0
    ;;

    (*)
    print -r "Aborting."
    if [[ $1 != -f ]]; then
      print "\
The function will be run again next time.  To prevent this, execute:
  touch $zdmsg/.zshrc"
    fi
    return 1
    ;;
  esac
fi


print -r "Attempting to extract information from manual pages..."
(man zshoptions | col -b > $tmpfile-man-options;
  man zshparam | col -b > $tmpfile-man-param) 2>/dev/null

while true; do
  clear
  print -nr "Please pick one of the following options:

(1)  Configure settings for history, i.e. command lines remembered
     and saved by the shell.\
${install_state[history]:+  ($install_state[history].)}

(2)  "
  if [[ $install_state[completion] = Recommended ]]; then
    print -nr "Configure"
  else
    print -nr "Use"
  fi
  print -r " the new completion system.\
${install_state[completion]:+  ($install_state[completion].)}

(3)  Configure how keys behave when editing command lines.\
${install_state[bindkey]:+  ($install_state[bindkey].)}

(4)  Pick some of the more common shell options.  These are simple \"on\"
     or \"off\" switches controlling the shell's features.  \
${install_state[options]:+  ($install_state[options].)}
"
  print -nr "(0)  Exit, "
  if (( save )); then
    print -r "saving the new settings.  They will take effect immediately."
  elif [[ -f $zd/.zshrc ]]; then
    print -r "leaving the existing $zdmsg/.zshrc alone."
  else
    print -r "creating a blank $zdmsg/.zshrc file."
  fi
  print -r "
(a)  Abort all settings and start from scratch.  Note this will overwrite
     any settings from $myname already in the startup file.
     It will not alter any of your other settings, however."
  if [[ $1 = -f ]]; then
    print -r "
(q)  Quit and do nothing else."
  else
    print -r "
(q)  Quit and do nothing else.  The function will be run again next time."
  fi

  read -k key$longprompt
  print

  case $key in
    ([qQ])
    break
    ;;

    ([aA])
    parsed_parameters=()
    state_parameters=()
    parsed_options=()
    state_options=()
    parsed_keymaps=()
    state_keymaps=()
    parsed_bindings=()
    state_bindings=()
    unparsed=()
    ;;

    (0)
    clear
    if (( save )); then
      if [[ -f $zd/.zshrc ]]; then
	cp $zd/.zshrc $zd/.zshrc.zni &&
	print -r "Copied old '$zdmsg/.zshrc' to '$zdmsg/.zshrc.zni'.
"
      fi

      __zni_save
      __zni_completion_save
    elif [[ ! -f $zd/.zshrc ]]; then
      print -r $msg >$zd/.zshrc
    fi
    if [[ $1 != -f ]]; then
      print -r "The function will not be run in future, but you can run
it yourself as follows:
  autoload -Uz $myname
  $myname -f

The code added to $zdmsg/.zshrc is marked by the lines
$startline
$endline
You should not edit anything between these lines if you intend to
run $myname again.  You may, however, edit any other part
of the file."
    fi
    break
    ;;

    (1)
    __zni_history_config
    ;;

    (2)
    __zni_completion_config
    ;;

    (3)
    __zni_bindkey_config
    ;;

    (4)
    __zni_options_config
    ;;
  esac
done

} always {
  # Tidy up: always executed unless the shell is stopped dead
  # in its tracks.
  unfunction -m $myname __zni_\*
  rm -f $tmpfile*
}