HEX
Server: Apache
System: Linux pdx1-shared-a1-38 6.6.104-grsec-jammy+ #3 SMP Tue Sep 16 00:28:11 UTC 2025 x86_64
User: mmickelson (3396398)
PHP: 8.1.31
Disabled: NONE
Upload Files
File: //lib/python3/dist-packages/mercurial/__pycache__/crecord.cpython-310.pyc
o

�]Lb��	@s�ddlmZddlZddlZddlZddlmZddlmZm	Z	ddl
mZmZm
Z
mZmZmZmZddlmZejZed�Zed	�Zed
�Zz
ddlZddlZej
Wn
eefyadZYnwGdd�de
j�Zd
d�ZGdd�de�Z Gdd�de e!�ZGdd�de �Z"Gdd�de �Z#Gdd�de �Z$d(dd�Z%d(dd�Z&dd�Z'd(dd �Z(ed!�ed"�ed#�ed$�d%�Z)Gd&d'�d'e�Z*dS))�)�absolute_importN�)�_)�getattr�open)�
diffhelper�encoding�error�patch�pycompat�scmutil�util)�
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__�rr�3/usr/lib/python3/dist-packages/mercurial/crecord.pyrFsrcCsto|�d�dkS)z�Return 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@sReZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�Zdd
�Z	ddd�Z
dd�ZdS)�	patchnodezVabstract class for patch graph nodes
    (i.e. patchroot, header, hunk, hunkline)
    cC�td���N�&method must be implemented by subclass��NotImplementedError��selfrrr�
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�nextsiblinge�zpatchnode.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.parentitemTcCs�z|j}Wntyd}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)�folded�AttributeErrorr&r)r")r!�
skipfolded�
itemfolded�nextitem�itemrrrr.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(�prevsiblinglastchild�prevsiblinglclcrrr�previtem�s	�zpatchnode.previtemN�T)rrrrr"r$r%r&r(r)r.r2rrrrrVs
.rc@seZdZdZdd�ZdS)r
z8
    list of header objects representing the patch.
    cCs|�|�|D]}||_qdS�N)�extendr
)r!�
headerlist�headerrrr�__init__�s
�zpatch.__init__N)rrrrr8rrrrr
�sr
c@sXeZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�Zdd
�Z	dd�Z
dd�Zdd�ZdS)�uiheaderzIpatch header

    xxx shouldn't we move this to mercurial/patch.py ?
    cs>|�_d�_d�_d�_d�_d�_�fdd��jD��_dS)NTFc�g|]}t|���qSr��uihunk��.0�hr rr�
<listcomp>��z%uiheader.__init__.<locals>.<listcomp>)�nonuiheader�applied�partialr*r
�
neverunfolded�hunks)r!r7rr rr8�szuiheader.__init__cC�t�}|�|�|��Sr4��stringio�pretty�getvalue�r!�xrrr�	prettystr��
zuiheader.prettystrcCs8t|j�}|j�|�}||dkr|j|d}|SdS�Nr)�lenr
�index)r!�numheadersinpatch�indexofthisheader�
nextheaderrrrr&�s
zuiheader.nextsiblingcCs*|j�|�}|dkr|j|d}|SdS�Nrr)r
rR)r!rT�previousheaderrrrr(�s
zuiheader.prevsiblingcC�dS)zj
        there is no 'real' parent item of a header that can be selected,
        so return None.
        Nrr rrrr)�szuiheader.parentitemcC�t|j�dkr|jdSdS��Lreturn the first child of this item, if one exists.  otherwise
        None.rN�rQrFr rrrr"�
zuiheader.firstchildcC�t|j�dkr|jdSdS��Kreturn the last child of this item, if one exists.  otherwise
        None.r���Nr\r rrrr$r]zuiheader.lastchildcC�|jS�z8return a list of all of the direct children of this node)rFr rrrr%�zuiheader.allchildrencC�t|j|�Sr4)rrB�r!�namerrr�__getattr__�zuiheader.__getattr__N)
rrrrr8rNr&r(r)r"r$r%rhrrrrr9�s
r9c@sHeZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�Zdd
�Z	dd�Z
dS)�
uihunklinez#represents a changed line in a hunkcCs||_d|_||_d|_dS�NTF)�linetextrC�hunkr*)r!rlrmrrrr8s
zuihunkline.__init__cCrbr4)rlr rrrrN'szuihunkline.prettystrcC�>t|jj�}|jj�|�}||dkr|jj|d}|SdSrP)rQrm�changedlinesrR)r!�numlinesinhunk�indexofthisline�nextlinerrrr&*�zuihunkline.nextsiblingcC�.|jj�|�}|dkr|jj|d}|SdSrV)rmrorR)r!rq�previouslinerrrr(4�
zuihunkline.prevsiblingcCrb�z%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@s�eZdZdZdZdd�Zdd�Zdd�Zd	d
�Zdd�Z	d
d�Z
dd�Zdd�Zdd�Z
dd�ZeZdd�Zdd�Zdd�Zdd�ZdS) r<z9ui patch hunk, wraps a hunk and keep track of ui behavior�cs@|�_�fdd�|jD��_|�_�j�_d�_d�_d�_dS)Ncr:r)rj�r>�liner rrr@TrAz#uihunk.__init__.<locals>.<listcomp>TF)	�_hunkrmror7�removed�originalremovedr*rCrD)r!rmr7rr rr8Rs
zuihunk.__init__cCrnrP)rQr7rFrR)r!�numhunksinheader�indexofthishunk�nexthunkrrrr&arszuihunk.nextsiblingcCrtrV)r7rFrR)r!r��previoushunkrrrr(krvzuihunk.prevsiblingcCrbrw�r7r rrrr)srdzuihunk.parentitemcCrYrZ�rQror rrrr"wr]zuihunk.firstchildcCr^r_r�r rrrr$r]zuihunk.lastchildcCrbrc)ror rrrr%�rdzuihunk.allchildrencCs0tdd�|jD��}tdd�|jD��}||fS)zchangedlines -> (n+,n-)cS�$g|]}|jr|���d�r|�qS)�+�rCrN�
startswith�r>�lrrrr@�����z'uihunk.countchanges.<locals>.<listcomp>cSr�)�-r�r�rrrr@�r�r�)r!�add�remrrr�countchanges�s����zuihunk.countchangescCs�|j|j}t|j�t|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}rQ�before�afterr�MISSING_NEWLINE_MARKER�added�fromline�toline�proc)r!�removedconvertedtocontext�
contextlen�fromlen�tolenr�r��
fromtolinerrr�
getfromtoline�s*�

�zuihunk.getfromtolinecCs�|��\|_|_|�|���g}|jD]}|��}|jr#|�|�q|�	d�r3|�d|dd��q|�d�
|j||j��dS)Nr�r�r�)
r�r�r}�writer�rorNrC�appendr��joinr�r�)r!�fp�hunklinelist�changedline�changedlinestrrrrr��s

� zuihunk.writecCrGr4rHrLrrrrN�rOzuihunk.prettystrc	Csg}g}d}|jD]G}|j}|jtjkrd}n9|jr9|�d�r*|�|dd��q	|�d�r8|�|dd��q	|�d�rP|�|dd��|�|dd��q	dd�|D�d	d�|D�}|rm|rm|d
dd
�|d
<|j}t�	|j
|j|j|j
|j||j�S)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.
        FTr�rNr�cS�g|]}d|�qS)s-%srr�rrrr@�z&uihunk.reversehunk.<locals>.<listcomp>cSr�)s+%srr�rrrr@r�ra)rorlrr�rCr�r�r|�patchmod�
recordhunkr7r�r�r�r�r�)r!�dels�adds�noeolr{�textrmr?rrr�reversehunk�s2


�
��zuihunk.reversehunkcCrer4)rr|rfrrrrhrizuihunk.__getattr__cCsd|��|jfS)Nz<hunk %r@%d>)�filenamer�r rrr�__repr__szuihunk.__repr__N)rrrr�
maxcontextr8r&r(r)r"r$r%r�r�r�rJrNr�rhr�rrrrr<Ms$
"8r<cCs�t|�}dd�|D�}t|�dkrgifSdd�|D�}||||d�}g}|D]<}|jrc|��s<tdd�|jD��dkrc|�|�d}	|jD]}
|
jrZ|�|
�|	rY|
j|	7_qF|	|
j|
j7}	qFq'||fS)z:interactively filter patch chunks into applied-only chunkscSsg|]
}t|tj�r|�qSr)�
isinstancer�r7)r>�crrrr@szfilterpatch.<locals>.<listcomp>rcSsg|]}t|��qSr)r9r=rrrr@ r�)�	operationcSsg|]}|jr|�qSr�rCr=rrrr@'rA)	�listrQrC�specialrFr�r�r}r�)r�chunks�
chunkselectorr��headers�	uiheaders�ret�appliedhunklist�hdr�	fixoffset�hnkrrr�filterpatchs.�


��r�c
Cs�|�td��t|||�}t�}}t�td�rt�tj�}z1t�	��t
�|j�Wd�n1s4wY|j
durA|j
�W||urMt�tj|�|jS||ur\t�tj|�ww)zk
    curses interface to get selection of chunks, and mark the applied flags
    of the chosen chunks.
    sstarting interactive selection
sSIGTSTPN)r�r�curseschunkselector�objectr
�safehasattr�signal�	getsignal�SIGTSTP�
with_lc_ctyper�wrapper�main�initexc�opts)rr6r�r��origsigtstp�sentinelrrrr�9s$

�
���r�cs��fdd�}|S)Ncs��g|�Ri|��Sr4r)�args�kwargs��f�testfnrr�uPsztestdecorator.<locals>.ur)r�r�r�rr�r�
testdecoratorOsr�cCs~t|||�}Gdd�dt�}|�|_|r<tj�|�r<t|d�}dd�|��D�}|��	|j	|�
d�dd�r;	|jSq-|jS)	zi
    test interface to get selection of chunks, and mark the applied flags
    of the chosen chunks.
    c@seZdZdd�Zdd�ZdS)z&testchunkselector.<locals>.dummystdscrcS�dSr4rr rrr�clear^�z,testchunkselector.<locals>.dummystdscr.clearcSr�r4rr rrr�refreshar�z.testchunkselector.<locals>.dummystdscr.refreshN)rrrr�r�rrrr�dummystdscr]sr��rcSsg|]}|�d��qS)�
)�rstrip)r>rMrrrr@hrAz%testchunkselector.<locals>.<listcomp>Tr��test)r�r��stdscr�os�path�existsr�	readlines�close�handlekeypressed�popr�)r�rr6r�r�r��testf�testcommandsrrr�testchunkselectorVs
�r�sSelect hunks to applysSelect hunks to discardsSelect hunks to keepsSelect hunks to record)sapplysdiscardskeepNc@s�eZdZd`dd�Zdd�Zdd�Zdd	�Zd
d�Zdad
d�Zdd�Z	dd�Z
dd�Zdd�Zdd�Z
d`dd�Zdd�Zdd�Zdd �Zdbd!d"�Zd#d$�Z						%	%	dcd&d'�Zd(d)�Zd*d+�Zd,d-�Zd.d/�Z	ddd0d1�Z	ddd2d3�Zded4d5�Zdfd6d7�Z	%dgd8d9�Zd:d;�Zd<d=�Z	%dhd>d?�Z 	%did@dA�Z!dBdC�Z"	djdDdE�Z#dFdG�Z$dHdI�Z%dJdK�Z&dLdM�Z'dNdO�Z(dPdQ�Z)dRdS�Z*dTdU�Z+dbdVdW�Z,dXdY�Z-dadZd[�Z.d\d]�Z/d^d_�Z0dS)kr�NcCs�t|�|_||_i|_d|_g|_|D]}|j�|�|j�|j�qi|_	i|_
t�|j�
dd��}|du|_|jd|_d|_d|_d|_d|_d|_d|_d|_d|_d|_d|_d|_d	|_|tvrmt�d
|��||_dS)NsuiscolorFrry�rr�Tsunexpected operation: %s) r
r6rr��errorstr�	chunklistr�r5rF�
colorpairs�colorpairnamesr�	parsebool�config�usecolor�currentselecteditem�lastapplieditem�selecteditemstartline�selecteditemendline�headerindentnumchars�hunkindentnumchars�hunklineindentnumchars�firstlineofpadtoprint�numpadlines�numstatuslines�linesprintedtopadsofar�commenttext�waslasttoggleallapplied�_headermessagesr	�ProgrammingErrorr�)r!r6rr�r?�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)r�r2�r!�currentitemr.rrr�uparrowevent�s

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)r�r(r)�recenterdisplayedarearrrr�uparrowshiftevent�s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)r�r.rrrr�downarrowevent�s
	
z"curseschunkselector.downarroweventcCs\|j}|��}|durz|����}Wntyd}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)r�r&r)r+rrrrr�downarrowshiftevent�s�z'curseschunkselector.downarrowshifteventFcs�|j��fdd�}���}|dur!||�s!|��}|dur!||�r|dur(�}n|��}|dur8|jr8|�|�||_|sC|��dSdS)Ncst|t���Sr4)r��type�r/�rrr�<lambda>sz2curseschunkselector.nextsametype.<locals>.<lambda>)r�r.r)r*�togglefoldedr)r!r��sametyper.�parentrr
r�nextsametype	s�
�z curseschunkselector.nextsametypecCs4|j}|��}|jr|�|�|dur|}||_dS)zL
        select (if possible) the first of this item's child-items.
        N)r�r"r*rrrrr�rightarrowevents

z#curseschunkselector.rightarroweventcCsV|j}t|t�s|js|j|d�dS|��}|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)r�r�rjr*rr)rrrr�leftarrowevent-s

z"curseschunkselector.leftarroweventcCsJ|j}t|t�r|js|j|d�dS	|��}|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)r�r�r9r*rr)rrrr�leftarrowshifteventFs
�
z'curseschunkselector.leftarrowshifteventcCsn|j}|j}|j}||j|jd}|d}|d}||kr(|�||�dS||kr5|�||�dSdS)z6scroll the screen to fully show the currently-selectedrryN)r�r�r��yscreensizer��scrolllines)r!�selstart�selend�padstart�padend�padstartbuffered�padendbufferedrrr�updatescroll\s�z curseschunkselector.updatescrollcCsB|j|7_|jdkrd|_|j|jdkr|jd|_dSdS)z>scroll the screen up (down) by numlines when numlines >0 (<0).rrN)r�r�)r!�numlinesrrrrns
�zcurseschunkselector.scrolllinescCs&|dur
|j}||_|j|_t|t�rEd|_|jr.|jD]}d|_|jD]}d|_q%qdS|jD]}d|_d|_|jD]}d|_q<q1dSt|t�r�d|_|jD]}|j|_qPdd�|j	jD�}d|v}d|v}dd�|j	jD�}d|v}|r�|j	�
�s�d|j	_d|j	_dSdSd|j	_|p�||j	_dSt|t��rdd�|jjD�}d|v}d|v}|r�d|j_d|j_n|r�d|j_d|j_nd|j_d|j_dd�|jj	jD�}	d|	v}
d|	v}d	d�|jj	jD�}d|v}
|
�r|jj	�
�s�d|jj	_d|jj	_dSdSd|jj	_|
�p||jj	_dSdS)
z�
        toggle the applied flag of the specified item.  if no item is specified,
        toggle the flag of the currently selected item.
        NFTcS�g|]}|j�qSrr��r>r�rrrr@��z3curseschunkselector.toggleapply.<locals>.<listcomp>cSr r�rDr!rrrr@�r"cSr rr�)r>�lnrrrr@�r"cSr rr�r!rrrr@���cSr rr#r!rrrr@�r%)
r�r�rCr�r9rDrFror<r7r�rjrm)r!r/r��hunkline�siblingappliedstatus�allsiblingsapplied�nosiblingsapplied�siblingspartialstatus�somesiblingspartial�parentsiblingsapplied�noparentsiblingsapplied�allparentsiblingsapplied�parentsiblingspartial�someparentsiblingspartialrrr�toggleapplyvs�



��

��



�
�

��
�

��zcurseschunkselector.toggleapplycCsN|jr|jD]
}|jr|�|�qn|jD]
}|js|�|�q|j|_dS)z%toggle the applied flag of all items.N)r�r6rCr1)r!r/rrr�	toggleall�s

��

�zcurseschunkselector.toggleallcCs6|jD]}|��D]}|��D]}|�|�qq	qdS)z`
        Flip all selections. Every selected line is unselected and vice
        versa.
        N)r6r%r1)r!r7rmr{rrr�flipselections�s
���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)r�r�r1r.rC)r!�	startitem�enditem�	directionr.�desiredstaterrr�toggleallbetween�s0��

�z$curseschunkselector.toggleallbetweencCs�|dur|j}|st|t�r5|jr5t|t�s|��|_}n|jr$d|_t|t�r5|��D]}|j|_q-t|ttf�rC|j|_dSdS)zMtoggle folded flag of specified item (defaults to currently
        selected)NF)r�r�r9rEr)r%r*r<)r!r/�
foldparent�childrrrrs

�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�
expandtabsr�colwidth)r!�instr�window�y�xstart�width�strwidth�	numspacesrrr�alignstring(s

zcurseschunkselector.alignstringTcCs�|�d�}t�ddd�|�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	}|
r�t|�}|�
d
�}t|�}||}|r�|�t�|�|�||7}|
r�|tjB}|r�t|�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]cSsdt�tt|���d��S)N�^�@)r�sysbytes�chr�ord�group��mrrrr[�z1curseschunkselector.printstring.<locals>.<lambda>�
Nra�r�s 
r�)r>�re�sub�stripr�r��getcolorpairr�A_UNDERLINE�A_BOLD�chunkpadr<rQr��addstrr�strfromlocal�	A_REVERSE�range�addch�ACS_CKBOARDrGr=r�)r!rAr��fgcolor�bgcolor�pair�pairname�attrlist�towin�align�
showwhtspc�	colorpair�textattrrBrC�t�origlen�strippedlen�numtrailingspaces�wscolorpair�i�extrawhitespace�linesprintedrrr�printstring7sh
 �
��

zcurseschunkselector.printstringc	Csp|jj}td�}td�}tt|�t|��}d||r|n|f}t|jdtd�td�td�td�|td	�g}|S)
z-> [str]. return segmentssspace/enter: selectsspace/enter: deselects%-*sr�s[x]=selected **=collapseds
c: confirmsq: aborts arrow keys: move/expand/collapses?: help)r�rCr�maxrQrr�)r!�selected�spaceselect�
spacedeselect�spacelen�
selectedlabel�segmentsrrr�_getstatuslinesegments�s$
��
z*curseschunkselector._getstatuslinesegmentscs��jdur
�jtd�g}nE���}�j}g}|}|D]7}t�|�}dd|o*|ddv}||t|�|kr?|�|�|}q|d||7<||t|�7}qt|��jkrgt|��_�j	�
�j�j��fdd	�|D�S)
z<() -> [str]. return short help used in the top status windowNsPress any key to continuer�rrs-[racsg|]}t�|�jd��qS)r)r�ellipsisr=r�r rrr@�rPz7curseschunkselector._getstatuslines.<locals>.<listcomp>)r�rrzr=rr?rQr�r��	statuswin�resize)r!�linesryrD�	lastwidth�s�w�seprr r�_getstatuslines�s$



z#curseschunkselector._getstatuslinesc	Cs�|j��|j��|j}z|��D]
}||j|dd�q|j��Wn
tjy-Ynw|jdur5dSz|�	�|�
�|j�|jd|jd|j
|j|jd�WdStjy_YdSw)N�legend�rcrr)r|�eraserYrrr�r�rr	r��	printitemrr�r�rr=)r!rrr{rrr�updatescreen�s4

�


��z curseschunkselector.updatescreencCs�|jrt|t�s|jrd}nd}nd}z.|jr/|d7}t|t�r,|j}||d7}W|SW|S|d7}t|t�r?|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**r�s  )rCr�rjrDr*r9�
changetyper+)r!r/�checkbox�
filestatusrrr�getstatusprefixstring�s0
	�
�

��
�z)curseschunkselector.getstatusprefixstringcCs
d}|��}|j�|�}|dkr"|js"||j|jd|j|dd�7}|j|r(dp)dtj	gd�}d}	|�
|�}
|jr;|rG|�d	�}|
|d}n|
|��}||j|j|||d
�7}|jr^|r�t
|�dkr�|dd�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.
        r�r�_F�rerf�selected�normal�rgrdrQ�rbrerNr�)rNr�rRr*rrrYr=rVrrXr��splitr�rQ)r!r7rtre�
ignorefolding�outstrr��
chunkindexrh�indentnumcharsr��textlist�linestrr{rrr�printheaders6��



�


�zcurseschunkselector.printheaderc
Cs�d}|jj�|�}|dkr||j|jd|j|dd�7}|j|r"dp#dtjgd�}|�	|�}d|j
|}	d	|���d
�}
||j|j|	|dd�7}||j|j|
||d�7}|j
r]|s]|S|jD]}d|jt|�|}||j|j||d�7}q`|S)
z!includes start/end line indicatorr�rr�Fr�r�r�r�s   rQr��re)r7rFrRrrrYr=rVrrXr�r�r�rUr*r�r�rQ)
r!rmrtrer�r��	hunkindexrhr��
lineprefix�frtoliner{r�rrr�printhunklinesbefore9s2��

�
�

�z(curseschunkselector.printhunklinesbeforecCsXd}|jr	|s	|S|�|�}|jD]}d|jt|�|}||j|j||d�7}q|S)Nr�r�r�)r*r�r�r�rQrrrY)r!rmrer�r�r�r{r�rrr�printhunklinesafteres


�z'curseschunkselector.printhunklinesafterc	Cs�d}|�|�}|���d�}|r|jdd�}n#|�d�r#|jdd�}n|�d�r/|jdd�}n|�d	�r:|jd
d�}d|j|}||j|j||dd
�7}||j|j|||dd�7}|S)Nr�rQr��rgr��additionr��deletion�\r�r�Fr�T)rbrerg)r�rNrUrVr�r�rrrY)	r!r&rtrer�r�r�rhr�rrr�printhunkchangedlinets&




��z(curseschunkselector.printhunkchangedlinecCs:|dur|j}|rd|_g}|j|||||d�d�|�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)
        Nrr�r�)r6r��_curseschunkselector__printitemr�)r!r/r��recursechildrenrer�rrrr��s	
�
zcurseschunkselector.printitemcCs@|j��\}}td|j|j�}|j|jd}||kp||kS)Nr�)rYr<�minr�r)r!rBr�miny�maxyrrr�outofdisplayedarea�sz&curseschunkselector.outofdisplayedareacCs<||ju}|r|r|j|_|j|dd�}|j|d|_|S)NF�r�r)r�r�r��getnumlinesdisplayedr�)r!r/r�rt�selecteditemlinesrrr�handleselection�s
��z#curseschunkselector.handleselectionc
Cs(|r|��rdS|�||�}t|t�r#|r#|D]}|�|||||�qt|t�rG|�|j||||d��|rE|jD]}|�|||||�q9|St|t	�r||j
jrR|r||�|j||||d��|rz|j
D]}	|�|	||||�qc|�|j|||d��|St|t�r�|jjr�|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)rer�r�)r�r�r�r
r�r9r�r�rFr<r7r*r�ror�rjrmr�)
r!r/r�r�r�rertr�r�r�rrr�__printitem�sf

�
��

�
�����

���
����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�)r�rQr=)r!r/r�r��patchdisplaystringrrrrr��s

�z(curseschunkselector.getnumlinesdisplayedcCspz,t��t�|j�\|_|_|j�|j	|j�|j
dd�d|_t�|j|j�|_
WdStjy7YdSw)zhandle window resizingT�r�rN)r�endwinr�termsizerr=rr|r}r�r�r��newpadrYr	)r!�n�framerrr�sigwinchhandlers�z#curseschunkselector.sigwinchhandlerc
Cs.|dur||jvr|j|}n`|durd}|durd}||f|jvr*|j||f}nEt|j�d}|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.
        Nrarrr�rR)
r�r�rQr�r�	init_pair�
color_pairr\rWrX)
r!r`rargrdrh�	pairindex�cvalri�
textattribrrrrVsF���

��z curseschunkselector.getcolorpaircOs|j|i|��dS)zsame as getcolorpair.N)rV)r!r�r�rrr�
initcolorpairRsz!curseschunkselector.initcolorpaircCs�td�}t�|jddd�}|�d�}|dg|j|jt|�d}z|D]
}|j||dd�q&Wn
tjy<Ynw|�	�z|j
�d��|��Wd	�Wd	S1sYwYWd	StjykYd	Sw)
z<print a help window to the screen.  exit after any keypress.s            [press any key to return to the patch-display]

The curses hunk selector allows you to interactively choose among the
changes you have made, and confirm only those changes you select for
further processing by the command you are running (such as commit,
shelve, or revert). After confirming the selected changes, the
unselected changes are still present in your working copy, so you can
use the hunk selector multiple times to split large changes into
smaller changesets. the following are valid keystrokes:

              x [space] : (un-)select item ([~]/[x] = partly/fully applied)
                [enter] : (un-)select item and go to next item of same type
                      A : (un-)select all items
                      X : (un-)select all items between current and most-recent
    up/down-arrow [k/j] : go to previous/next unfolded item
        pgup/pgdn [K/J] : go to previous/next item of same type
 right/left-arrow [l/h] : go to child item / parent item
 shift-left-arrow   [H] : go to parent header / fold selected header
                      g : go to the top
                      G : go to the bottom
                      f : fold / unfold item, hiding/revealing its children
                      F : fold / unfold parent item and all of its ancestors
                 ctrl-l : scroll the selected line to the top of the screen
                      m : edit / resume editing the commit message
                      e : edit the currently selected hunk
                      a : toggle all selections
                      c : confirm selected changes
                      r : review/edit and confirm selected changes
                      q : quit without confirming (no changes will be made)
                      ? : help (what you're currently reading)rrQr�rr�r��crecordN)
rr�newwinrr�r�rQrrr	r�r�timeblockedsection�getkey)r!�helptext�helpwin�	helplinesr{rrr�
helpwindowVs.�!
���
&��zcurseschunkselector.helpwindowcCsRt��t��t��|j�|j|j���|_t��|j	�
�|j	�d�dS)z?Create a temporary commit message editing window on the screen.rN)r�raw�
def_prog_moder�r�editr��username�cbreakr�r��keypadr rrr�commitMessageWindow�s
z'curseschunkselector.commitMessageWindowcCs6|jd|_|j}	|��}|durn|}q
||_dS)zT
        Handle 'g' to navigate to the top most file in the ncurses window.
        rTN)r6r�r)rrrr�handlefirstlineevent�s�
z(curseschunkselector.handlefirstlineeventcCsF|j}|��}|dur|��}|durn|}|dus||_|��dS)a�
        Handle 'G' to navigate to the bottom most file/hunk/line depending
        on the whether the fold is active or not.

        If the bottom most file is folded, it navigates to that file and
        stops there. If the bottom most file is unfolded, it navigates to
        the bottom most hunk in that file and stops there. If the bottom most
        hunk is unfolded, it navigates to the bottom most line in that hunk.
        N)r�r.rrrrr�handlelastlineevent�s
�z'curseschunkselector.handlelastlineeventcCs�t�|jddd�}z|�d�}|D]
}|j||dd�qWn
tjy'Ynw|j��|��z"|j�	d��t
|j���}Wd�W|S1sLwYW|Sty_d}Y|Sw)zMdisplay an informational window, then wait for and return a
        keypress.rrQr�r�r�N)
rr�rr�rrr	r�r�rr�rK�getch�
ValueError)r!�
windowtext�
confirmwinr~r{�responserrr�confirmationwindow�s,
��
����z&curseschunkselector.confirmationwindowcCs`td�}|j�d��
|�|�}Wd�n1swY|dur%d}|���d�r.dSdS)zPask for 'y' to be pressed to confirm selected. return True if
        confirmed.s�If you answer yes to the following, your currently chosen patch chunks
will be loaded into an editor. To modify the patch, make the changes in your
editor and save. To accept the current patch as-is, close the editor without
saving.

note: don't add/remove lines unless you also modify the range information.
      failing to follow this rule will result in the commit aborting.

are you sure you want to review/edit and confirm the selected changes [yn]?
r�Nr�rBTF)rrr�r��lowerr�)r!�confirmtextr�rrr�reviewcommit�s��z curseschunkselector.reviewcommitcCs|jdd�|��dS)a
        once we scrolled with pg up pg down we can be pointing outside of the
        display zone. we print the patch with towin=False to compute the
        location of the selected item even though it is outside of the displayed
        zone and then update the scroll.
        Fr�N)r�rr rrrr�sz)curseschunkselector.recenterdisplayedareacs�dd�}dd�}|dur|j}t|t�rdSt|t�r|��}t|t�s&dS|��j�|�}|j|j	}}|||�}|durF|sD||�dS|j
��j�|�}	�jd|	�}
�j|	dd�}|d}�fdd	�|jD�}
td
d	�|
D��}tdd	�|
D��}||||}|D]	}|j|7_q�|
D]}d|_
q�|
|
|�_|��r�|
|g|�_�|_t�j�|kr��j||_|s�||�dSdS)
z3
        edit the currently selected chunk
        cSsP|jdd�d|_t�|j|j�|_|��|j��|j	��|j�
d�dS)NTr�r)r�r�rr�r=rYrr�r�r|r�r rrr�updateui�s

z0curseschunkselector.toggleedit.<locals>.updateuic
Ss*|dur|j�td��|j�d�dS|j��r)|j�td��|j�d�dSt�}|�tt�|j�|�|�|�z=z
|jj|�	�ddd�}Wn#t
jyo}z|j|_
WYd}~W|j��|j��dSd}~wwW|j��|j��n|j��|j��wdd�|��D�}t�|�S)	Ns cannot edit patch for whole filerQs!cannot edit patch for binary filer�sdiff)�actioncSsg|]}|�d�s|d�qS)�#rQ)r�rzrrrr@s��zOcurseschunkselector.toggleedit.<locals>.editpatchwitheditor.<locals>.<listcomp>)rr�rr7�binaryrI�diffhelptext�hunkhelptextr�rKr	�Abort�messager�r�r�r��
splitlinesr��
parsepatch)r!�chunkr
�excrrr�editpatchwitheditors<


���

��
z;curseschunkselector.toggleedit.<locals>.editpatchwitheditorNrrcr:rr;r=r�rrr@9rAz2curseschunkselector.toggleedit.<locals>.<listcomp>cSr r)r�r=rrrr@:r"cSr r)r}r=rrrr@;r"F)r�r�r9rjr)r<rFrRr�r}r7�sumr�r*�
emptypatchrQ)r!r/r�r�r��	itemindex�beforeadded�
beforeremoved�
newpatches�editedhunkindex�hunksbefore�
hunksafter�newpatchheader�newhunks�newadded�
newremoved�offsetr?rr�r�
toggleedit�sN"



�zcurseschunkselector.toggleeditcCs(|j}|sdS|D]}|jrdSq	dSrk)r6rF)r!r/r7rrrr�Ls�zcurseschunkselector.emptypatchcCs@|dvr
|��dS|dvr|��dS|dvr|��dS|dvr(|��dS|dvr2|��dS|dvr<|��dS|dvrF|��dS|dvrQt�t	d	���|d
vr[|�
�dS|dvradS|d
vrr|��rpd|jd<dSdS|r|dvrd|jd<dS|dvr�|�
�dS|dvr�|�
�|j|d�dS|dvr�|��dS|dvr�|��dS|dvr�|j|d�dS|dvr�|��dS|dvr�|jdd�dS|dvr�|��dS|dvr�|��dS|dvr�|��dS|dv�r|��|j��|j��dS|tj�d�fv�r|�|j�|j��|j��dSdS)zd
        Perform actions based on pressed keys.

        Return true to exit the main loop.
        )�k�KEY_UP)�K�	KEY_PPAGE)�j�KEY_DOWN)�J�	KEY_NPAGE)r��	KEY_RIGHT)r?�KEY_LEFT)�H�	KEY_SLEFT)�qs	user quit)�a)r�T)�rsreview)�R)� rM)r��	KEY_ENTERr�)�X)�A)�e)r�)�F)r9rN)�g�KEY_HOME)�G�KEY_END)�?�LN)rrr	r
rrrr	�
CanceledErrorrr3r�r�r1rr8r2r�rr�r�r�r�r�r�r�r�ascii�ctrlrr�)r!�
keypressedr�rrrr�Ust
�



�z$curseschunkselector.handlekeypressedc
Csft�}}t�td�rt�tj|j�}z|�|�W||ur%t�tj|�SS||ur2t�tj|�ww)zP
        method to be wrapped by curses.wrapper() for selecting chunks.
        sSIGWINCH)r�r
r�r��SIGWINCHr��_main)r!r��origsigwinchr�rrrr��s


��zcurseschunkselector.maincCs&||_d|_|j��\|_|_t��zt��Wn
tjy&d|_	Ynw|j�
�zt�d�Wn
tjy=Ynw|jdddd�|jtj
tjdd�|jtjddd�|jtjddd�|jtj
tjdd�t�|jddd�|_|j�d	�t�d	|j�|_|jd
d�d	|_zt�|j|j�|_Wntjy�ttd��|_YdSw|j|jdd
�|_	|��z'|j� d��
|j�!�}Wd�n1s�wY|j"dur�d|_"Wq�Wntjy�d}Ynw|�#|�r�nq�|j$dk�rt%�&dd|j$�}|dk�r|j$|j'd<dSdSdS)NFrr�r�r�r�r�r�rTr�s&this diff is too large to be displayedr�r�sfoobarr�s(?m)^\s.*(\n|$)smessage)(r�r��getmaxyxrr=r�start_color�use_default_colorsr	r�r��curs_setr��COLOR_WHITE�
COLOR_MAGENTA�	COLOR_RED�COLOR_GREEN�
COLOR_BLUEr�r�r|r�r�rYr�r�rrr�r�r�rr�r�r�r�r�rSrTr�)r!r�r�whitespaceremovedrrrr�s~
�
�
�
�����
��
�
�
�zcurseschunkselector._mainr4)F)NF)NNNNNTTF)FTF)TF)FT)NFTTr3)NFT)NNNN)1rrrr8rrr	r
rrrrrrr1r2r3r8rrGrrrzr�r�r�r�r�r�r�r�r�r�r�r�r�rVr�r�r�r�r�r�r�rr�r�r�r�rrrrrr�xsz
B

^

*
�e"
�.
�
,

�	
�C
�
�;4

Y
	Ar�r4)+�
__future__rr�rSr��i18nrrrr�rrr	r
r�rr
�utilsrrIr�r��
patchhelptextr�curses.ascii�ImportErrorr+r�rrr�rr�r9rjr<r�r�r�r�rr�rrrr�<module>sV
$	��
�
�	kN2
J
#
�