o ]Lb @sddlmZddlZddlZddlZddlmZddlmZm Z ddl m Z m Z m Z mZmZmZmZddlmZejZedZed Zed Zz ddlZddlZej Wn eefyadZYnwGd d d e jZd dZGdddeZ Gddde e!ZGddde Z"Gddde Z#Gddde Z$d(ddZ%d(ddZ&ddZ'd(dd Z(ed!ed"ed#ed$d%Z)Gd&d'd'eZ*dS)))absolute_importN)_)getattropen) diffhelperencodingerrorpatchpycompatscmutilutil) stringutils# To remove '-' lines, make them ' ' lines (context). # To remove '+' lines, delete them. # Lines starting with # will be removed from the patch. s,# # If the patch applies cleanly, the edited hunk will immediately be # added to the record list. If it does not apply cleanly, a rejects file # will be generated. You can use that when you try again. If all lines # of the hunk are removed, then the edit is aborted and the hunk is left # unchanged. s# # If the patch applies cleanly, the edited patch will immediately # be finalised. If it does not apply cleanly, rejects files will be # generated. You can use those when you try again. c@seZdZdZdS) fallbackerrorzDError that indicates the client should try to fallback to text mode.N)__name__ __module__ __qualname____doc__rr3/usr/lib/python3/dist-packages/mercurial/crecord.pyrFsrcCsto|ddkS)zReturn True if the user wants to use curses This method returns True if curses is found (and that python is built with it) and that the user has the correct flag for the ui. s chunkselectorscurses)curses interface)uirrr checkcursesMsrc@sReZdZdZddZddZddZdd Zd d Zd d Z dddZ ddZ dS) patchnodezVabstract class for patch graph nodes (i.e. patchroot, header, hunk, hunkline) cCtdN&method must be implemented by subclassNotImplementedErrorselfrrr firstchild[zpatchnode.firstchildcCrrrr rrr lastchild^r#zpatchnode.lastchildcCr)z8Return a list of all of the direct children of this noderrr rrr allchildrenaszpatchnode.allchildrencCr)z Return the closest next item of the same type where there are no items of different types between the current item and this closest item. If no such item exists, return None. rrr rrr nextsiblingezpatchnode.nextsiblingcCr)z Return the closest previous item of the same type where there are no items of different types between the current item and this closest item. If no such item exists, return None. rrr rrr prevsiblingmr'zpatchnode.prevsiblingcCrrrr rrr parentitemur#zpatchnode.parentitemTcCsz|j}Wn tyd}Ynw|r5|r5|}|dur3z |}W|Sty2d}Y|Sw|S|}|dur?|S|}|durI|Sz|}|durW|WS|WStyiYdSw)ax Try to return the next item closest to this item, regardless of item's type (header, hunk, or hunkline). If skipfolded == True, and the current item is folded, then the child items that are hidden due to folding will be skipped when determining the next item. If it is not possible to get the next item, return None. FN)foldedAttributeErrorr&r)r")r! skipfolded itemfoldednextitemitemrrrr.xs<     zpatchnode.nextitemcCsP|}|dur$|}|dur"|js"|}|dur |js |S|S|S|S)z Try to return the previous item closest to this item, regardless of item's type (header, hunk, or hunkline). If it is not possible to get the previous item, return None. N)r(r$r*r))r!r(prevsiblinglastchildprevsiblinglclcrrrprevitems zpatchnode.previtemNT) rrrrr"r$r%r&r(r)r.r2rrrrrVs  .rc@seZdZdZddZdS)r z8 list of header objects representing the patch. cCs|||D]}||_qdSN)extendr )r! headerlistheaderrrr__init__s zpatch.__init__N)rrrrr8rrrrr s r c@sXeZdZdZddZddZddZdd Zd d Zd d Z ddZ ddZ ddZ dS)uiheaderzIpatch header xxx shouldn't we move this to mercurial/patch.py ? cs>|_d_d_d_d_d_fddjD_dS)NTFcg|]}t|qSruihunk.0hr rr z%uiheader.__init__..) nonuiheaderappliedpartialr*r neverunfoldedhunks)r!r7rr rr8szuiheader.__init__cCt}|||Sr4stringioprettygetvaluer!xrrr prettystr zuiheader.prettystrcCs8t|j}|j|}||dkr|j|d}|SdSNr)lenr index)r!numheadersinpatchindexofthisheader nextheaderrrrr&s   zuiheader.nextsiblingcCs*|j|}|dkr|j|d}|SdSNrr)r rR)r!rTpreviousheaderrrrr(s zuiheader.prevsiblingcCdS)zj there is no 'real' parent item of a header that can be selected, so return None. Nrr rrrr)szuiheader.parentitemcCt|jdkr |jdSdSLreturn the first child of this item, if one exists. otherwise None.rNrQrFr rrrr" zuiheader.firstchildcCt|jdkr |jdSdSKreturn the last child of this item, if one exists. otherwise None.rNr\r rrrr$ r]zuiheader.lastchildcC|jSz8return a list of all of the direct children of this node)rFr rrrr%zuiheader.allchildrencC t|j|Sr4)rrBr!namerrr __getattr__ zuiheader.__getattr__N) rrrrr8rNr&r(r)r"r$r%rhrrrrr9s  r9c@sHeZdZdZddZddZddZdd Zd d Zd d Z ddZ dS) uihunklinez#represents a changed line in a hunkcCs||_d|_||_d|_dSNTF)linetextrChunkr*)r!rlrmrrrr8s zuihunkline.__init__cCrbr4)rlr rrrrN'szuihunkline.prettystrcC>t|jj}|jj|}||dkr|jj|d}|SdSrP)rQrm changedlinesrR)r!numlinesinhunkindexofthislinenextlinerrrr&*  zuihunkline.nextsiblingcC.|jj|}|dkr|jj|d}|SdSrV)rmrorR)r!rq previouslinerrrr(4 zuihunkline.prevsiblingcCrbz%return the parent to the current item)rmr rrrr)<rdzuihunkline.parentitemcCrX)r[Nrr rrrr"@zuihunkline.firstchildcCrX)r`Nrr rrrr$Frxzuihunkline.lastchildN) rrrrr8rNr&r(r)r"r$rrrrrjs   rjc@seZdZdZdZddZddZddZd d Zd d Z d dZ ddZ ddZ ddZ ddZeZddZddZddZddZdS) r<z9ui patch hunk, wraps a hunk and keep track of ui behaviorcs@|_fdd|jD_|_j_d_d_d_dS)Ncr:r)rjr>liner rrr@TrAz#uihunk.__init__..TF) _hunkrmror7removedoriginalremovedr*rCrD)r!rmr7rr rr8Rs zuihunk.__init__cCrnrP)rQr7rFrR)r!numhunksinheaderindexofthishunknexthunkrrrr&arszuihunk.nextsiblingcCrtrV)r7rFrR)r!r previoushunkrrrr(krvzuihunk.prevsiblingcCrbrwr7r rrrr)srdzuihunk.parentitemcCrYrZrQror rrrr"wr]zuihunk.firstchildcCr^r_rr rrrr$r]zuihunk.lastchildcCrbrc)ror rrrr%rdzuihunk.allchildrencCs0tdd|jD}tdd|jD}||fS)zchangedlines -> (n+,n-)cS$g|]}|jr|dr|qS)+rCrN startswithr>lrrrr@ z'uihunk.countchanges..cSr)-rrrrrr@rr)r!addremrrr countchangesszuihunk.countchangescCs|j|j}t|jt|j|}|jr!|jdtjkr!|d8}||j}||j}|j|j }}|dkrJ|dkr>|d8}|dkrJ|dkrJ|d8}d|||||j oVd|j f}|S)Nrarrs@@ -%d,%d +%d,%d @@%s  ) r~r}rQbeforeafterrMISSING_NEWLINE_MARKERaddedfromlinetolineproc)r!removedconvertedtocontext contextlenfromlentolenrr fromtolinerrr getfromtolines*   zuihunk.getfromtolinecCs|\|_|_||g}|jD]}|}|jr#||q| dr3|d|ddq|d |j ||j dS)Nrrr) rrr}writerrorNrCappendrjoinrr)r!fp hunklinelist changedlinechangedlinestrrrrrs    z uihunk.writecCrGr4rHrLrrrrNrOzuihunk.prettystrc Csg}g}d}|jD]G}|j}|jtjkrd}n9|jr9|dr*||ddq |dr8||ddq |drP||dd||ddq dd|Dd d|D}|rm|rm|d dd |d <|j}t |j |j |j |j |j||jS) aSreturn a recordhunk which is the reverse of the hunk Assuming the displayed patch is diff(A, B) result. The returned hunk is intended to be applied to B, instead of A. For example, when A is "0 1 2 6 " and B is "0 3 4 5 6 ", and the user made the following selection: 0 [x] -1 [x]: selected [ ] -2 [ ]: not selected [x] +3 [ ] +4 [x] +5 6 This function returns a hunk like: 0 -3 -4 -5 +1 +4 6 Note "4" was first deleted then added. That's because "4" exists in B side and "-4" must exist between "-3" and "-5" to make the patch applicable to B. FTrrNrcSg|]}d|qS)s-%srrrrrr@z&uihunk.reversehunk..cSr)s+%srrrrrr@rra)rorlrrrCrrr|patchmod recordhunkr7rrrrr)r!delsaddsnoeolr{textrmr?rrr reversehunks2     zuihunk.reversehunkcCrer4)rr|rfrrrrhrizuihunk.__getattr__cCsd||jfS)Nz )filenamerr rrr__repr__szuihunk.__repr__N)rrrr maxcontextr8r&r(r)r"r$r%rrrrJrNrrhrrrrrr<Ms$ "8 r<c Cst|}dd|D}t|dkrgifSdd|D}||||d}g}|D]<}|jrc|scrrrr@szfilterpatch..rcSsg|]}t|qSr)r9r=rrrr@ r) operationcSsg|]}|jr|qSrrCr=rrrr@'rA) listrQrCspecialrFrrr}r) rchunks chunkselectorrheaders uiheadersretappliedhunklisthdr fixoffsethnkrrr filterpatchs.    rc Cs|tdt|||}t}}ttdrttj}z1t t |j Wdn1s4wY|j durA|j W||urMttj||jS||ur\ttj|ww)zk curses interface to get selection of chunks, and mark the applied flags of the chosen chunks. sstarting interactive selection sSIGTSTPN)rrcurseschunkselectorobjectr safehasattrsignal getsignalSIGTSTP with_lc_ctyperwrappermaininitexcopts)rr6rr origsigtstpsentinelrrrr9s$      rcsfdd}|S)Ncsg|Ri|Sr4r)argskwargsftestfnrruPsztestdecorator..ur)rrrrrr testdecoratorOsrcCs~t|||}Gdddt}||_|r.dummystdscrcSdSr4rr rrrclear^z,testchunkselector..dummystdscr.clearcSrr4rr rrrrefresharz.testchunkselector..dummystdscr.refreshN)rrrrrrrrr dummystdscr]s rrcSsg|]}|dqS) )rstrip)r>rMrrrr@hrAz%testchunkselector..Trtest) rrstdscrospathexistsr readlinesclosehandlekeypressedpopr)rrr6rrrtestf testcommandsrrrtestchunkselectorVs  rsSelect hunks to applysSelect hunks to discardsSelect hunks to keepsSelect hunks to record)sapplysdiscardskeepNc@seZdZd`ddZddZddZdd Zd d Zdad dZddZ ddZ ddZ ddZ ddZ d`ddZddZddZdd Zdbd!d"Zd#d$Z      % % dcd&d'Zd(d)Zd*d+Zd,d-Zd.d/Z ddd0d1Z ddd2d3Zded4d5Zdfd6d7Z %dgd8d9Zd:d;Zdd?Z %did@dAZ!dBdCZ" djdDdEZ#dFdGZ$dHdIZ%dJdKZ&dLdMZ'dNdOZ(dPdQZ)dRdSZ*dTdUZ+dbdVdWZ,dXdYZ-dadZd[Z.d\d]Z/d^d_Z0dS)krNcCst||_||_i|_d|_g|_|D]}|j||j|jqi|_ i|_ t |j dd}|du|_|jd|_d|_d|_d|_d|_d|_d|_d|_d|_d|_d|_d|_d |_|tvrmtd |||_dS) NsuiscolorFrryrrTsunexpected operation: %s) r r6rrerrorstr chunklistrr5rF colorpairscolorpairnamesr parseboolconfigusecolorcurrentselecteditemlastapplieditemselecteditemstartlineselecteditemendlineheaderindentnumcharshunkindentnumcharshunklineindentnumcharsfirstlineofpadtoprint numpadlinesnumstatuslineslinesprintedtopadsofar commenttextwaslasttoggleallapplied_headermessagesr ProgrammingErrorr)r!r6rrr?uicolorrrrr8ys<     zcurseschunkselector.__init__cC$|j}|}|dur |}||_dS)aM try to select the previous item to the current item that has the most-indented level. for example, if a hunk is selected, try to select the last hunkline of the hunk prior to the selected hunk. or, if the first hunkline of a hunk is currently selected, then select the hunk itself. N)rr2r! currentitemr.rrr uparrowevents  z curseschunkselector.uparroweventcCs<|j}|}|dur|}|dur|}||_|dS)z select (if possible) the previous item on the same level as the currently selected item. otherwise, select (if possible) the parent-item of the currently selected item. N)rr(r)recenterdisplayedarearrrruparrowshiftevents z%curseschunkselector.uparrowshifteventcCr)ag try to select the next item to the current item that has the most-indented level. for example, if a hunk is selected, select the first hunkline of the selected hunk. or, if the last hunkline of a hunk is currently selected, then select the next hunk, if one exists, or if not, the next header if one exists. N)rr.rrrrdownarrowevents   z"curseschunkselector.downarroweventcCs\|j}|}|durz|}Wn tyd}Ynw|dur%|}||_|dS)z select (if possible) the next item on the same level as the currently selected item. otherwise, select (if possible) the next item on the same level as the parent item of the currently selected item. N)rr&r)r+rrrrrdownarrowshiftevents  z'curseschunkselector.downarrowshifteventFcs|jfdd}}|dur!||s!|}|dur!||r|dur(}n|}|dur8|jr8||||_|sC|dSdS)Ncst|tSr4)rtyper/rrr sz2curseschunkselector.nextsametype..)rr.r)r* togglefoldedr)r!rsametyper.parentrr r nextsametype s   z curseschunkselector.nextsametypecCs4|j}|}|jr|||dur|}||_dS)zL select (if possible) the first of this item's child-items. N)rr"r*rrrrrrightarrowevents  z#curseschunkselector.rightarroweventcCsV|j}t|ts|js|j|ddS|}|dur&|}|js&|j|d||_dS)z if the current item can be folded (i.e. it is an unfolded header or hunk), then fold it. otherwise try select (if possible) the parent of this item. r N)rrrjr*rr)rrrrleftarrowevent-s    z"curseschunkselector.leftarroweventcCsJ|j}t|tr|js|j|ddS |}|durn|}q||_dS)z select the header of the current item (or fold current item if the current item is already a header). r N)rrr9r*rr)rrrrleftarrowshifteventFs   z'curseschunkselector.leftarrowshifteventcCsn|j}|j}|j}||j|jd}|d}|d}||kr(|||dS||kr5|||dSdS)z6scroll the screen to fully show the currently-selectedrryN)rrr yscreensizer scrolllines)r!selstartselendpadstartpadendpadstartbufferedpadendbufferedrrr updatescroll\sz curseschunkselector.updatescrollcCsB|j|7_|jdkrd|_|j|jdkr|jd|_dSdS)z>scroll the screen up (down) by numlines when numlines >0 (<0).rrN)rr)r!numlinesrrrrns  zcurseschunkselector.scrolllinescCs&|dur |j}||_|j |_t|trEd|_|jr.|jD]}d|_|jD]}d|_q%qdS|jD]}d|_d|_|jD]}d|_qrrrrr@z3curseschunkselector.toggleapply..cSr rrDr!rrrr@r"cSr rr)r>lnrrrr@r"cSr rrr!rrrr@cSr rr#r!rrrr@r%) rrrCrr9rDrFror<r7rrjrm)r!r/rhunklinesiblingappliedstatusallsiblingsappliednosiblingsappliedsiblingspartialstatussomesiblingspartialparentsiblingsappliednoparentsiblingsappliedallparentsiblingsappliedparentsiblingspartialsomeparentsiblingspartialrrr toggleapplyvs                   zcurseschunkselector.toggleapplycCsN|jr|jD] }|jr||qn|jD] }|js||q|j |_dS)z%toggle the applied flag of all items.N)rr6rCr1)r!r/rrr togglealls    zcurseschunkselector.toggleallcCs6|jD]}|D]}|D]}||qq qdS)z` Flip all selections. Every selected line is unselected and vice versa. N)r6r%r1)r!r7rmr{rrrflipselectionss    z"curseschunkselector.flipselectionscCs|jr |j|jkr|dS|j}|j}dD]}|}|r-||kr-|}|r-||ks#|r1n||}}q|s;dS|}|jj }||kr_|j|krS|j|d|}||ksHdSdS)zOtoggle applied on or off for all items in range [lastapplied, current].N)sforwardsreverser )rrr1r.rC)r! startitemenditem directionr. desiredstaterrrtoggleallbetweens0        z$curseschunkselector.toggleallbetweencCs|dur|j}|st|tr5|jr5t|ts||_}n|jr$d|_t|tr5|D]}|j |_q-t|ttfrC|j |_dSdS)zMtoggle folded flag of specified item (defaults to currently selected)NF)rrr9rEr)r%r*r<)r!r/ foldparentchildrrrrs    z curseschunkselector.togglefoldedcCsB|\}}|j}|d}t|}||||}|d|S)z add whitespace to the end of a string in order to make it fill the screen in the x direction. the current cursor position is taken into account when making this calculation. the string can span multiple lines. r)getyx xscreensize expandtabsrcolwidth)r!instrwindowyxstartwidthstrwidth numspacesrrr alignstring(s    zcurseschunkselector.alignstringTc Cs|d}tddd|d}|dur|} n+|dur"|j|} n!|dur(d}|dur.d}||f|jvr=|j||f} n|||} |durIg}| dkrW|D]} | | O} qOntjtj fD] } | |vrg| | O} q]|j \} }d }| rt |}| d }t |}||}|r|t|| ||7}| r| tjB}|rt|D] }|tj|q|d |7}| r|r|d |}||| n|||}||7}|t ||j}|j|7_|S) a print the string, text, with the specified colors and attributes, to the specified curses window object. the foreground and background colors are of the form curses.color_xxxx, where xxxx is one of: [black, blue, cyan, green, magenta, red, white, yellow]. if pairname is provided, a color pair will be looked up in the self.colorpairnames dictionary. attrlist is a list containing text attributes in the form of curses.a_xxxx, where xxxx can be: [bold, dim, normal, standout, underline]. if align == True, whitespace is added to the printed string such that the string stretches to the right border of the window. if showwhtspc == True, trailing whitespace of a string is highlighted. r;s[\x00-\x08\x0a-\x1f]cSsdttt|dS)N^@)r sysbyteschrordgroupmrrrr[z1curseschunkselector.printstring.. Nrars r)r>resubstriprr getcolorpairr A_UNDERLINEA_BOLDchunkpadr<rQraddstrr strfromlocal A_REVERSErangeaddch ACS_CKBOARDrGr=r)r!rArfgcolorbgcolorpairpairnameattrlisttowinalign showwhtspc colorpairtextattrrBrCtoriglen strippedlennumtrailingspaces wscolorpairiextrawhitespace linesprintedrrr printstring7sh          zcurseschunkselector.printstringc Csp|jj}td}td}tt|t|}d||r|n|f}t|jdtdtdtdtd|td g}|S) z-> [str]. return segmentssspace/enter: selectsspace/enter: deselects%-*srs[x]=selected **=collapseds c: confirmsq: aborts arrow keys: move/expand/collapses?: help)rrCrmaxrQrr)r!selected spaceselect spacedeselectspacelen selectedlabelsegmentsrrr_getstatuslinesegmentss$  z*curseschunkselector._getstatuslinesegmentscsjdur jtdg}nE}j}g}|}|D]7}t|}dd|o*|ddv}||t||kr?|||}q|d||7<||t|7}qt|jkrgt|_j jjfdd |DS) z<() -> [str]. return short help used in the top status windowNsPress any key to continuerrrs-[racsg|] }t|jdqS)r)rellipsisr=rr rrr@rPz7curseschunkselector._getstatuslines..) rrrzr=rr?rQrr statuswinresize)r!linesryrD lastwidthswseprr r_getstatusliness$    z#curseschunkselector._getstatuslinesc Cs|j|j|j}z|D] }||j|ddq|jWn tjy-Ynw|jdur5dSz| | |j|j d|j d|j |j |jdWdStjy_YdSw)Nlegendrcrr)r|eraserYrrrrrr r printitemrrrrr=)r!rrr{rrr updatescreens4      z curseschunkselector.updatescreencCs|jrt|ts|jrd}nd}nd}z.|jr/|d7}t|tr,|j}||d7}W|SW|S|d7}t|tr?|d7}W|SW|StyO|d7}Y|Sw)zx create a string to prefix a line with which indicates whether 'item' is applied and/or folded. s[~]s[x]s[ ]s**rs )rCrrjrDr*r9 changetyper+)r!r/checkbox filestatusrrrgetstatusprefixstrings0      z)curseschunkselector.getstatusprefixstringcCs d}|}|j|}|dkr"|js"||j|jd|j|dd7}|j|r(dp)dtj gd}d} | |} |jr;|rG| d } | | d} n| | } ||j|j| ||d 7}|jr^|rt | d kr| d d D]} d | t | | } ||j|j| ||d 7}qj|S)z print the header to the pad. if countlines is True, don't print anything, but just count the number of lines which would be printed. rr_FrerfselectednormalrgrdrQrbrerNr)rNrrRr*rrrYr=rVrrXrsplitrrQ)r!r7rtre ignorefoldingoutstrr chunkindexrhindentnumcharsrtextlistlinestrr{rrr printheader s6          zcurseschunkselector.printheaderc Csd}|jj|}|dkr||j|jd|j|dd7}|j|r"dp#dtjgd}| |}d|j |} d | d } ||j|j| |dd7}||j|j| ||d 7}|j r]|s]|S|jD]} d|jt|| } ||j|j| |d 7}q`|S) z!includes start/end line indicatorrrrFrrrrs rQrre)r7rFrRrrrYr=rVrrXrrrrUr*rrrQ) r!rmrtrerr hunkindexrhr lineprefixfrtoliner{rrrrprinthunklinesbefore9s2     z(curseschunkselector.printhunklinesbeforecCsXd}|jr |s |S||}|jD]}d|jt||}||j|j||d7}q|S)Nrrr)r*rrrrQrrrY)r!rmrerrrr{rrrrprinthunklinesafteres   z'curseschunkselector.printhunklinesafterc Csd}||}|d}|r|jdd}n#|dr#|jdd}n|dr/|jdd}n |d r:|jd d}d |j|}||j|j||d d 7}||j|j|||dd7}|S)NrrQrrgradditionrdeletion\rrFrT)rbrerg)rrNrUrVrrrrrY) r!r&rtrerrrrhrrrrprinthunkchangedlinets&       z(curseschunkselector.printhunkchangedlinecCs:|dur|j}|r d|_g}|j|||||dd|S)z use __printitem() to print the the specified item.applied. if item is not specified, then print the entire patch. (hiding folded elements, etc. -- see __printitem() docstring) Nrrr)r6r_curseschunkselector__printitemr)r!r/rrecursechildrenrerrrrrs   zcurseschunkselector.printitemcCs@|j\}}td|j|j}|j|jd}||kp||kS)Nr)rYr<minrr)r!rBrminymaxyrrroutofdisplayedareasz&curseschunkselector.outofdisplayedareacCs<||ju}|r|r|j|_|j|dd}|j|d|_|S)NFrr)rrrgetnumlinesdisplayedr)r!r/rrtselecteditemlinesrrrhandleselections  z#curseschunkselector.handleselectionc Cs(|r|rdS|||}t|tr#|r#|D] }||||||qt|trG||j||||d|rE|jD] }||||||q9|St|t r||j j rR|r|||j ||||d|rz|j D] } || ||||qc||j|||d|St|tr|jj r|r||j|||d|S)a{ recursive method for printing out patch/header/hunk/hunk-line data to screen. also returns a string with all of the content of the displayed patch (not including coloring, etc.). if ignorefolding is True, then folded items are printed out. if recursechildren is False, then only print the item without its child items. N)rerr)rrrr rr9rrrFr<r7r*rrorrjrmr) r!r/rrrrertrrrrrr __printitemsf           zcurseschunkselector.__printitemcCs$|j|||dd}t||j}|S)aY return the number of lines which would be displayed if the item were to be printed to the display. the item will not be printed to the display (pad). if no item is given, assume the entire patch. if ignorefolding is True, folded items will be unfolded when counting the number of lines. Fr)rrQr=)r!r/rrpatchdisplaystringrrrrrs  z(curseschunkselector.getnumlinesdisplayedcCspz,tt|j\|_|_|j|j |j|j ddd|_ t |j |j|_ WdStjy7YdSw)zhandle window resizingTrrN)rendwinr termsizerr=rr|r}rrrnewpadrYr )r!nframerrrsigwinchhandler sz#curseschunkselector.sigwinchhandlerc Cs.|dur||jvr|j|}n`|durd}|durd}||f|jvr*|j||f}nEt|jd}|jrTt|||t|}|j||f<|durSt||j|<nd}|durf|dkratj}||j|<|}|j||f<|durug}|dkr|D]}||O}q{|Stjtj fD] } | |vr|| O}q|S)a get a curses color pair, adding it to self.colorpairs if it is not already defined. an optional string, name, can be passed as a shortcut for referring to the color-pair. by default, if no arguments are specified, the white foreground / black background color-pair is returned. it is expected that this function will be used exclusively for initializing color pairs, and not curses.init_pair(). attrlist is used to 'flavor' the returned color-pair. this information is not stored in self.colorpairs. it contains attribute values like curses.A_BOLD. NrarrrrR) rrrQrr init_pair color_pairr\rWrX) r!r`rargrdrh pairindexcvalri textattribrrrrVsF   z curseschunkselector.getcolorpaircOs|j|i|dS)zsame as getcolorpair.N)rV)r!rrrrr initcolorpairRsz!curseschunkselector.initcolorpaircCstd}t|jddd}|d}|dg|j|jt|d}z|D] }|j||ddq&Wn tjy<Ynw| z|j d| Wd Wd S1sYwYWd StjykYd Sw) z.updateuic Ss*|dur|jtd|jddS|jr)|jtd|jddSt}|tt|j|||z=z |jj| ddd}Wn#t j yo}z|j |_ WYd}~W|j|jdSd}~wwW|j|jn |j|jwdd|D}t|S) Ns cannot edit patch for whole filerQs!cannot edit patch for binary filersdiff)actioncSsg|] }|ds|dqS)#rQ)rrzrrrr@s zOcurseschunkselector.toggleedit..editpatchwitheditor..)rrrr7binaryrI diffhelptext hunkhelptextrrKr Abortmessagerrrr splitlinesr parsepatch)r!chunkr excrrreditpatchwitheditors<           z;curseschunkselector.toggleedit..editpatchwitheditorNrrcr:rr;r=rrrr@9rAz2curseschunkselector.toggleedit..cSr r)rr=rrrr@:r"cSr r)r}r=rrrr@;r"F)rrr9rjr)r<rFrRrr}r7sumrr* emptypatchrQ)r!r/rrr itemindex beforeadded beforeremoved newpatcheseditedhunkindex hunksbefore hunksafternewpatchheadernewhunksnewadded newremovedoffsetr?rrr toggleeditsN"       zcurseschunkselector.toggleeditcCs(|j}|sdS|D]}|jrdSq dSrk)r6rF)r!r/r7rrrrLszcurseschunkselector.emptypatchcCs@|dvr |dS|dvr|dS|dvr|dS|dvr(|dS|dvr2|dS|dvr<|dS|dvrF|dS|dvrQtt d |d vr[| dS|d vrad S|d vrr| rpd |j d<d SdS|r|dvrd |j d<d S|dvr| dS|dvr| |j|ddS|dvr|dS|dvr|dS|dvr|j|ddS|dvr|dS|dvr|jd ddS|dvr|dS|dvr|dS|dvr|dS|dvr||j|jdS|tjdfvr||j|j|jdSdS)zd Perform actions based on pressed keys. Return true to exit the main loop. )kKEY_UP)K KEY_PPAGE)jKEY_DOWN)J KEY_NPAGE)r KEY_RIGHT)r?KEY_LEFT)H KEY_SLEFT)qs user quit)a)rT)rsreview)R) rM)r KEY_ENTERr)X)A)e)r)F)r9rN)gKEY_HOME)GKEY_END)?LN)rrr r rrrr CanceledErrorrr3rrr1rr8r2rrrrrrrrrrasciictrlrr)r! keypressedrrrrrUst                      z$curseschunkselector.handlekeypressedc Csft}}ttdrttj|j}z||W||ur%ttj|SS||ur2ttj|ww)zP method to be wrapped by curses.wrapper() for selecting chunks. sSIGWINCH)rr rrSIGWINCHr_main)r!r origsigwinchrrrrrs    zcurseschunkselector.maincCs&||_d|_|j\|_|_tztWn tjy&d|_ Ynw|j zt dWn tjy=Ynw|j dddd|j tj tjdd|j tjddd|j tjddd|j tj tjddt|jddd|_|jd td |j|_|jd d d |_z t|j|j|_Wntjyttd |_YdSw|j|jdd |_ |z'|j d |j!}Wdn1swY|j"durd|_"WqWn tjyd}Ynw|#|rnq|j$dkrt%&dd|j$}|dkr|j$|j'd<dSdSdS)NFrrrrrrrrTrs&this diff is too large to be displayedrrsfoobarrs(?m)^\s.*(\n|$)smessage)(rrgetmaxyxrr=r start_coloruse_default_colorsr rrcurs_setr COLOR_WHITE COLOR_MAGENTA COLOR_RED COLOR_GREEN COLOR_BLUErrr|rrrYrrrrrrrrrrrrrrSrTr)r!rrwhitespaceremovedrrrrs~           zcurseschunkselector._mainr4)F)NF)NNNNNTTF)FTF)TF)FT)NFTTr3)NFT)NNNN)1rrrr8rrr r rrrrrrr1r2r3r8rrGrrrzrrrrrrrrrrrrrrVrrrrrrrrrrrrrrrrrrxsz B  ^  * e" . ,    C  ;4  Y A rr4)+ __future__rrrSri18nrr rrrrr r rr r utilsrrIrr patchhelptextr curses.ascii ImportErrorr+rrrrrrr9rjr<rrrrrrrrrrsV  $    k N2 J #