
                            S r SSKJr  SSKrSSKrSSKrSSKrSSKrSSKJ	r	J
r
  SSKJrJrJr  SSKJr  Sr\R$                  " S	5      r\R$                  " S
5      r\R$                  " S5      r\R$                  " S5      r\R$                  " S5      r\R$                  " S5      r\R2                  " 5       r " S S\5      r " S S\5      r " S S\5      rg)zB
The `Document` that implements all the text operations/querying.
    )unicode_literalsN)rangemap   )SelectionTypeSelectionState	PasteMode)ClipboardData)Documentz ([a-zA-Z0-9_]+|[^a-zA-Z0-9_\s]+)z!^([a-zA-Z0-9_]+|[^a-zA-Z0-9_\s]+)z&^(([a-zA-Z0-9_]+|[^a-zA-Z0-9_\s]+)\s*)z([^\s]+)z	^([^\s]+)z^([^\s]+\s*)c                   B    \ rS rSrSrS r\r\r\r\r	\r
\r\r\r\rSrg)_ImmutableLineList(   z{
Some protection for our 'lines' list, which is assumed to be immutable in the cache.
(Useful for detecting obvious bugs.)
c                     [        S5      e)Nz%Attempt to modifiy an immutable list.)NotImplementedError)selfakws      *lib/third_party/prompt_toolkit/document.py_error_ImmutableLineList._error-   s    !"IJJ     N)__name__
__module____qualname____firstlineno____doc__r   __setitem__appendclearextendinsertpopremovereversesort__static_attributes__r   r   r   r   r   (   s<    K KFEFF
CFGDr   r   c                       \ rS rSrS rSrg)_DocumentCache;   c                      S U l         S U l        g N)linesline_indexesr   s    r   __init___DocumentCache.__init__<   s    
 !r   )r.   r-   N)r   r   r   r   r0   r'   r   r   r   r)   r)   ;   s    !r   r)   c                      \ rS rSrSrSrSGS jrS r\S 5       r	\S 5       r
\S	 5       r\S
 5       r\S 5       r\S 5       r\S 5       r\S 5       r\S 5       r\S 5       r\S 5       r\S 5       r\S 5       r\S 5       r\S 5       rSHS jr\S 5       r\S 5       r\S 5       r\S 5       rS rS rS r\S 5       r \S 5       r!S  r"  SIS" jr#SJS# jr$SKS$ jr%SJS% jr&SLS& jr'  SMS' jr(SJS( jr)SLS) jr*SNS* jr+SLS+ jr,SLS, jr-SOS- jr.SOS. jr/SOS/ jr0SOS0 jr1SPS1 jr2SPS2 jr3SQS3 jr4SQS4 jr5SRS5 jr6S6 r7S7 r8SJS8 jr9S9 r:S: r;S; r<S< r=S= r>S> r?S? r@\AR                  S!4S@ jrCSA rDSLSB jrESLSC jrFSD rGSE rHSFrIg)Sr   D   a  
This is a immutable class around the text and cursor position, and contains
methods for querying this data, e.g. to give the text before the cursor.

This class is usually instantiated by a :class:`~prompt_toolkit.buffer.Buffer`
object, and accessed as the `document` property of that class.

:param text: string
:param cursor_position: int
:param selection: :class:`.SelectionState`
)_text_cursor_position
_selection_cacheNc           	         [        U[        R                  5      (       d
   SU-  5       eUb  [        U[        5      (       d   eUb0  U[	        U5      ::  d!   [        SU< S[	        U5      < 35      5       eUc  [	        U5      nXl        X l        X0l         [        U R                     U l        g ! [         a/    [        5       U l        U R                  [        U R                  '    g f = f)NzGot %rzcursor_position=z, len_text=)
isinstancesix	text_typer   lenAssertionErrorr4   r5   r6   _text_to_document_cachetextr7   KeyErrorr)   )r   r?   cursor_position	selections       r   r0   Document.__init__R   s    $..?4?. Jy.$I$III &/SY*F 	R5Dc$iPIR 	RF "!$iO
 
 /#	=1$))<DK 	=(*DK15#DII.	=s   B1 16C*)C*c                 n    U R                   R                  < SU R                  < SU R                  < S3$ )N(z, ))	__class__r   r?   rA   r/   s    r   __repr__Document.__repr__v   s#    #~~66		4CWCWXXr   c                     U R                   $ )zThe document text. )r4   r/   s    r   r?   Document.texty   s     zzr   c                     U R                   $ )zThe document cursor position. )r5   r/   s    r   rA   Document.cursor_position~   s     $$$r   c                     U R                   $ )z!:class:`.SelectionState` object. )r6   r/   s    r   rB   Document.selection   s     r   c                 6    U R                  S5      =(       d    S$ )z2Return character under cursor or an empty string. r    _get_char_relative_to_cursorr/   s    r   current_charDocument.current_char   s     0039r9r   c                 6    U R                  S5      =(       d    S$ )z7Return character before the cursor or an empty string. rQ   rR   r/   s    r   char_before_cursorDocument.char_before_cursor   s     004::r   c                 4    U R                   S U R                   $ r,   r?   rA   r/   s    r   text_before_cursorDocument.text_before_cursor   s    yy/$..00r   c                 4    U R                   U R                  S  $ r,   r[   r/   s    r   text_after_cursorDocument.text_after_cursor   s    yy--.//r   c                 B    U R                   R                  S5      u    pU$ )z2Text from the start of the line until the cursor. 
)r\   
rpartition)r   _r?   s      r   current_line_before_cursor#Document.current_line_before_cursor   s#     ,,77=
1r   c                 D    U R                   R                  S5      u  n  nU$ )z0Text from the cursor until the end of the line. rb   )r_   	partition)r   r?   rd   s      r   current_line_after_cursor"Document.current_line_after_cursor   s%     ++55d;
ar   c                     U R                   R                  c3  [        U R                  R	                  S5      5      U R                   l        U R                   R                  $ )z
Array of all the lines.
rb   )r7   r-   r   r?   splitr/   s    r   r-   Document.lines   sB     ;;$ 2499??43H IDKK{{   r   c                 @   U R                   R                  cr  [        [        U R                  5      nS/nUR
                  nSnU H  nXES-   -  nU" U5        M     [        U5      S:  a  UR                  5         X R                   l        U R                   R                  $ )z7
Array pointing to the start indexes of all the lines.
r   r   )r7   r.   r   r<   r-   r   r#   )r   line_lengthsindexesr   posline_lengths         r   _line_start_indexesDocument._line_start_indexes   s     ;;##+sDJJ/L cG^^FC+Q&s  ,
 7|a'.KK${{'''r   c                 4    U R                   U R                  S $ )zI
Array of the lines starting from the current line, until the last line.
N)r-   cursor_position_rowr/   s    r   lines_from_currentDocument.lines_from_current   s    
 zz$22344r   c                 ,    [        U R                  5      $ )zReturn the number of lines in this document. If the document ends
with a trailing \n, that counts as the beginning of a new line. )r<   r-   r/   s    r   
line_countDocument.line_count   s     4::r   c                 4    U R                   U R                  -   $ )znReturn the text on the line where the cursor is. (when the input
consists of just one line, it equals `text`. )re   ri   r/   s    r   current_lineDocument.current_line   s     ..1O1OOOr   c                 n    U R                   n[        U5      [        UR                  5       5      -
  nUSU $ )z@The leading whitespace in the left margin of the current line.  N)r}   r<   lstrip)r   r}   lengths      r   "leading_whitespace_in_current_line+Document.leading_whitespace_in_current_line   s9     ((\"S)<)<)>%??GV$$r   c                 \     U R                   U R                  U-      $ ! [         a     gf = f)z?
Return character relative to cursor position, or empty string
rQ   )r?   rA   
IndexError)r   offsets     r   rS   %Document._get_char_relative_to_cursor   s3    	99T11F:;; 		s    
++c                      U R                   S:H  $ )z%
True when we are at the first line.
r   )rv   r/   s    r   on_first_lineDocument.on_first_line   s    
 ''1,,r   c                 :    U R                   U R                  S-
  :H  $ )z$
True when we are at the last line.
r   )rv   rz   r/   s    r   on_last_lineDocument.on_last_line   s    
 ''4??Q+>>>r   c                 @    U R                  U R                  5      u  pU$ )z
Current row. (0-based.)
_find_line_start_indexrA   )r   rowrd   s      r   rv   Document.cursor_position_row   s!    
 ,,T-A-AB
r   c                 Z    U R                  U R                  5      u  pU R                  U-
  $ )z
Current column. (0-based.)
r   )r   rd   line_start_indexs      r   cursor_position_colDocument.cursor_position_col  s/     #99$:N:NO##&666r   c                 X    U R                   n[        R                  " X!5      S-
  nX2U   4$ )z
For the index of a character at a certain line, calculate the index of
the first character on that line.

Return (row, index) tuple.
r   )rs   bisectbisect_right)r   indexrp   rq   s       r   r   Document._find_line_start_index  s1     **!!'1A5CL  r   c                 6    U R                  U5      u  p#X-
  nX$4$ )zp
Given an index for the text, return the corresponding (row, col) tuple.
(0-based. Returns (0, 0) for index=0.)
)r   )r   r   r   	row_indexcols        r   translate_index_to_position$Document.translate_index_to_position  s%     44U;xr   c           
          U R                   U   nU R                  U   nU[        S[	        U[        U5      5      5      -  n[        S[	        U[        U R                  5      5      5      nU$ ! [         aG    US:  a   U R                   S   nU R                  S   n N}U R                   S   nU R                  S   n Nf = f)z
Given a (row, col) tuple, return the corresponding index.
(Row and col params are 0-based.)

Negative row/col values are turned into zero.
r   rW   )rs   r-   r   maxminr<   r?   )r   r   r   resultlines        r   translate_row_col_to_index#Document.translate_row_col_to_index)  s    		&--c2F::c?D 	#aS#d),-- QFC		N34  	&Qw11!4zz!}11"5zz"~	&s   A- -.B>B>=B>c                 F    U R                   [        U R                  5      :H  $ )z0True when the cursor is at the end of the text. )rA   r<   r?   r/   s    r   is_cursor_at_the_endDocument.is_cursor_at_the_endB  s     ##s499~55r   c                      U R                   S;   $ )z1True when the cursor is at the end of this line. )rb   rQ   )rT   r/   s    r   is_cursor_at_the_end_of_line%Document.is_cursor_at_the_end_of_lineG  s       J..r   c                 f    U R                   R                  XR                  5      U R                  :H  $ )z=
`True` when this substring is found at the cursor position.
)r?   findrA   )r   subs     r   has_match_at_current_position&Document.has_match_at_current_positionL  s(     yy~~c#7#78D<P<PPPr   r   c                    [        U[        5      (       d   eU(       a  U R                  nOU R                  nU(       d  [	        U5      S:X  a  gUSS nU(       a  [
        R                  OSn[
        R                  " [
        R                  " U5      Xg5      n [        U5       H>  u  pU	S-   U:X  d  M  U(       a  U
R                  S5      s  $ U
R                  S5      S-   s  $    g! [         a     gf = f)z
Find `text` after the cursor, return position relative to the cursor
position. Return `None` if nothing was found.

:param count: Find the n-th occurance.
r   Nr   )r9   boolri   r_   r<   re
IGNORECASEfinditerescape	enumeratestartStopIteration)r   r   in_current_lineinclude_current_positionignore_casecountr?   flagsiteratorimatchs              r   r   Document.findR  s     +t,,,,11D))D'4yA~ABx!,!;;ryy~t;	%h/q5E>/${{1~-${{1~11 0  		s$   C' 4C' C' $C' '
C43C4c                     U(       a  [         R                  OSn[         R                  " [         R                  " U5      U R                  U5       Vs/ s H  oDR                  5       PM     sn$ s  snf )z\
Find all occurances of the substring. Return a list of absolute
positions in the document.
r   )r   r   r   r   r?   r   )r   r   r   r   r   s        r   find_allDocument.find_allt  sH    
 "-!#%;;ryy~tyy%#PQ#Pa	#PQQQs   A.c                    U(       a  U R                   SSS2   nOU R                  SSS2   nU(       a  [        R                  OSn[        R                  " [        R
                  " USSS2   5      XV5      n [        U5       H.  u  pUS-   U:X  d  M  U	R                  S5      * [        U5      -
  s  $    g! [         a     gf = f)z
Find `text` before the cursor, return position relative to the cursor
position. Return `None` if nothing was found.

:param count: Find the n-th occurance.
NrW   r   r   )
re   r\   r   r   r   r   r   r   r<   r   )
r   r   r   r   r   before_cursorr   r   r   r   s
             r   find_backwardsDocument.find_backwards|  s      ;;DbDAM 33DbD9M!,!;;ryyTrT3]J	%h/q5E>"[[^+c#h66 0  		s   8B6 B6 3B6 6
CCc                     U R                   SS R                  5       (       a  gU R                   U R                  US9S $ )zh
Give the word before the cursor.
If we have whitespace before the cursor this returns an empty string.
rW   NrQ   WORD)r\   isspacefind_start_of_previous_word)r   r   s     r   get_word_before_cursorDocument.get_word_before_cursor  sF    
 ""23'//11**4+K+KQU+K+V+WXXr   c                     U R                   SSS2   nU(       a  [        O[        nUR                  U5      n [	        U5       H"  u  pgUS-   U:X  d  M  UR                  S5      * s  $    g! [         a     gf = f)
Return an index relative to the cursor position pointing to the start
of the previous word. Return `None` if nothing was found.
NrW   r   )r\   _FIND_BIG_WORD_RE_FIND_WORD_REr   r   endr   r   r   r   r\   regexr   r   r   s           r   r   $Document.find_start_of_previous_word  sw     "44TrT:%)!}>>"45	%h/q5E>"YYq\>) 0  		s   A* A* 'A* *
A76A7c                   ^ U R                   SSS2   nU R                  nU4S jnU" U5      R                  U5      nU" U5      R                  U5      nT(       db  U(       a[  U(       aT  U R                  U R                  S-
     n	U R                  U R                     n
[
        R                  S-   nX;   X;   :w  a  SnU(       a  UR                  S5      * OSU(       a  UR                  S5      4$ S4$ )z
Return the relative boundaries (startpos, endpos) of the current word under the
cursor. (This is at the current line, because line boundaries obviously
don't belong to any word.)
If not on a word, this returns (0,0)
NrW   c                 <   > [         [        [        [        S.TU 4   $ )N))FF)FT)TF)TT)_FIND_CURRENT_WORD_RE1_FIND_CURRENT_WORD_INCLUDE_TRAILING_WHITESPACE_RE_FIND_CURRENT_BIG_WORD_RE5_FIND_CURRENT_BIG_WORD_INCLUDE_TRAILING_WHITESPACE_RE)include_whitespacer   s    r   	get_regex;Document.find_boundaries_of_current_word.<locals>.get_regex  s)     5P8S	
 '(* *r   r   0123456789_r   )re   ri   searchr?   rA   stringascii_lettersr   )r   r   include_leading_whitespaceinclude_trailing_whitespacer\   r_   r   match_beforematch_afterc1c2alphabets    `          r   find_boundaries_of_current_word(Document.find_boundaries_of_current_word  s     "<<TrTB ::	* !!;<CCDVW ;<CCDUV 4//!34B4//0B++m;HBN3# &2lq!!q"-KOOA
 	
34
 	
r   c                 v    U R                  US9u  p#U R                  U R                  U-   U R                  U-    $ )zv
Return the word, currently below the cursor.
This returns an empty string when the cursor is on a whitespace region.
r   )r   r?   rA   )r   r   r   r   s       r   get_word_under_cursorDocument.get_word_under_cursor  s@    
 99t9D
yy--5t7K7Kc7QRRr   c                 P   US:  a  U R                  U* US9$ U(       a  [        O[        nUR                  U R                  5      n [        U5       HA  u  pVUS:X  a  UR                  S5      S:X  a  US-  nUS-   U:X  d  M0  UR                  S5      s  $    g! [         a     gf = f)z}
Return an index relative to the cursor position pointing to the start
of the next word. Return `None` if nothing was found.
r   r   r   r   N)find_previous_word_beginningr   r   r   r_   r   r   r   r   r   r   r   r   r   r   s          r   find_next_word_beginning!Document.find_next_word_beginning  s    
 1944E64MM%)!}>>$"8"89		%h/6ekk!n1QJEq5E> ;;q>) 0  		s   7B B B 
B%$B%c                 b   US:  a  U R                  U* US9$ U(       a  U R                  nOU R                  SS nU(       a  [        O[        nUR	                  U5      n [        U5       H1  u  pxUS-   U:X  d  M  UR                  S5      n	U(       a  U	s  $ U	S-   s  $    g! [         a     gf = f)z{
Return an index relative to the cursor position pointing to the end
of the next word. Return `None` if nothing was found.
r   r   r   N)find_previous_word_endingr_   r   r   r   r   r   r   )
r   r   r   r   r?   r   iterabler   r   values
             r   find_next_word_endingDocument.find_next_word_ending  s    
 1911T1JJ#))D))!"-D%)!}>>$'	%h/q5E>!IIaLE/$$qy( 0  		s$    B! ;B! B! B! !
B.-B.c                    US:  a  U R                  U* US9$ U(       a  [        O[        nUR                  U R                  SSS2   5      n [        U5       H"  u  pVUS-   U:X  d  M  UR                  S5      * s  $    g! [         a     gf = f)r   r   r   NrW   r   )r   r   r   r   r\   r   r   r   r   s          r   r   %Document.find_previous_word_beginning  s    
 1900vD0II%)!}>>$"9"9$B$"?@	%h/q5E>"YYq\>) 0  		s   A? (A? <A? ?
BBc                    US:  a  U R                  U* US9$ U R                  SS U R                  SSS2   -   nU(       a  [        O[        nUR                  U5      n [        U5       HE  u  pgUS:X  a  UR                  S5      S:X  a  US-  nUS-   U:X  d  M0  UR                  S5      * S-   s  $    g! [         a     gf = f)z
Return an index relative to the cursor position pointing to the end
of the previous word. Return `None` if nothing was found.
r   r   Nr   rW   )	r   r_   r\   r   r   r   r   r   r   r   s           r   r   "Document.find_previous_word_ending#  s    
 19--UF-FF!33BQ7$:Q:QRVTVRV:WW%)!}>>"45		%h/6ekk!n1QJEq5E>!KKN?Q.. 0  		s   7B4 B4 1B4 4
C Cc                     Sn[        U R                  U R                  S-   S 5       H%  u  pEU" U5      (       a
  SU-   nUS-  nUS:X  d  M$    U$    U$ )zV
Look downwards for empty lines.
Return the line index, relative to the current line.
Nr   r   r   r-   rv   r   
match_funcr   r   r   r   s         r   find_next_matching_line Document.find_next_matching_line;  se    
 $TZZ0H0H10L0M%NOKE$U
z P r   c                     Sn[        U R                  SU R                   SSS2   5       H%  u  pEU" U5      (       a
  SU-
  nUS-  nUS:X  d  M$    U$    U$ )zT
Look upwards for empty lines.
Return the line index, relative to the current line.
NrW   r   r   r  r  s         r   find_previous_matching_line$Document.find_previous_matching_lineL  si    
 $TZZ0I1I1I%J4R4%PQKE$e
z R r   c                 `    US:  a  U R                  U* 5      $ [        U R                  U5      * $ )z$
Relative position for cursor left.
r   )get_cursor_right_positionr   r   r   r   s     r   get_cursor_left_position!Document.get_cursor_left_position]  s4     19115&99T--u555r   c                 p    US:  a  U R                  U* 5      $ [        U[        U R                  5      5      $ )z%
Relative position for cursor_right.
r   )r  r   r<   ri   r  s     r   r  "Document.get_cursor_right_positionf  s6     1900%885#d<<=>>r   c                     US:  d   eUc  U R                   OUnU R                  [        SU R                  U-
  5      U5      U R                  -
  $ )z
Return the relative cursor position (character index) where we would be if the
user pressed the arrow-up button.

:param preferred_column: When given, go to this column instead of
                         staying at the current column.
r   r   )r   r   r   rv   rA   r   r   preferred_columncolumns       r   get_cursor_up_positionDocument.get_cursor_up_positiono  s]     zz-=-E))K[..4++e34f>@D@T@TU 	Ur   c                     US:  d   eUc  U R                   OUnU R                  U R                  U-   U5      U R                  -
  $ )z
Return the relative cursor position (character index) where we would be if the
user pressed the arrow-down button.

:param preferred_column: When given, go to this column instead of
                         staying at the current column.
r   )r   r   rv   rA   r  s       r   get_cursor_down_position!Document.get_cursor_down_position}  sV     zz-=-E))K[..$$u,f68<8L8LM 	Mr   c                 N   U R                   U:X  a  gUc  [        U R                  5      nO[        [        U R                  5      U5      nSn[	        U R
                  S-   U5       H=  nU R                  U   nXa:X  a  US-  nO
Xb:X  a  US-  nUS:X  d  M/  XPR
                  -
  s  $    g)z
Find the right bracket enclosing current position. Return the relative
position to the cursor position.

When `end_pos` is given, don't look past the position.
r   Nr   )rT   r<   r?   r   r   rA   )r   left_chright_chend_posstackr   cs          r   find_enclosing_bracket_right%Document.find_enclosing_bracket_right  s     (?$))nG#dii.'2G t++a/9A		!A|

z//// :r   c                 
   U R                   U:X  a  gUc  SnO[        SU5      nSn[        U R                  S-
  US-
  S5       H=  nU R                  U   nXb:X  a  US-  nO
Xa:X  a  US-  nUS:X  d  M/  XPR                  -
  s  $    g)z
Find the left bracket enclosing current position. Return the relative
position to the cursor position.

When `start_pos` is given, don't look past the position.
r   Nr   rW   )rT   r   r   rA   r?   )r   r  r  	start_posr!  r   r"  s          r   find_enclosing_bracket_left$Document.find_enclosing_bracket_left  s     'IAy)I t++a/QCA		!A}

z//// Dr   c                     S H[  u  p4U R                   U:X  a  U R                  X4US9=(       d    Ss  $ U R                   U:X  d  MB  U R                  X4US9=(       d    Ss  $    g)z
Return relative cursor position of matching [, (, { or < bracket.

When `start_pos` or `end_pos` are given. Don't look past the positions.
)z()z[]z{}z<>)r   r   )r&  )rT   r#  r'  )r   r&  r   ABs        r   find_matching_bracket_position'Document.find_matching_bracket_position  si     +DA  A%88w8OTSTT""a'77	7RWVWW	 + r   c                     U R                   * $ )z1Relative position for the start of the document. )rA   r/   s    r   get_start_of_document_position'Document.get_start_of_document_position  s    %%%%r   c                 F    [        U R                  5      U R                  -
  $ )z/Relative position for the end of the document. )r<   r?   rA   r/   s    r   get_end_of_document_position%Document.get_end_of_document_position  s    499~ 4 444r   c                     U(       a>  U R                   n[        U5      [        UR                  5       5      -
  U R                  -
  $ [        U R                  5      * $ )z.Relative position for the start of this line. )r}   r<   r   r   re   )r   after_whitespacer}   s      r   get_start_of_line_position#Document.get_start_of_line_position  sM    ,,L|$s<+>+>+@'AADD\D\\\88999r   c                 ,    [        U R                  5      $ )z,Relative position for the end of this line. )r<   ri   r/   s    r   get_end_of_line_position!Document.get_end_of_line_position  s    41122r   c                 h    [        U R                  R                  5       5      U R                  -
  S-
  $ )zB
Relative position for the last non blank character of this line.
r   )r<   r}   rstripr   r/   s    r   'last_non_blank_of_current_line_position0Document.last_non_blank_of_current_line_position  s.     4$$++-.1I1IIAMMr   c                 v    [        U R                  5      nU R                  n[        S[	        X!5      5      nX-
  $ )z
Return the relative cursor position for this column at the current
line. (It will stay between the boundaries of the line in case of a
larger number.)
r   )r<   r}   r   r   r   )r   r  rr   current_columns       r   get_column_cursor_position#Document.get_column_cursor_position  s9     $++,11QK01&&r   c                     U R                   (       a0  [        U R                  U R                   R                  /5      u  pX4$ U R                  U R                  p!X4$ )z
Return (from, to) tuple of the selection.
start and end position are included.

This doesn't take the selection type into account. Use
`selection_ranges` instead.
)rB   sortedrA   original_cursor_position)r   from_tos      r   selection_rangeDocument.selection_range  sS     >> 4 4dnn6]6]^_IE y ,,d.B.B2yr   c           	   #   l  #    U R                   (       Ga  [        U R                  U R                   R                  /5      u  pU R                   R                  [
        R                  :X  a  U R                  U5      u  p4U R                  U5      u  pV[        XF/5      u  pFU R                  n[        X5S-   5       HI  n[        Xx   5      n	XI:  d  M  U R                  X5      U R                  U[        U	S-
  U5      5      4v   MK     gU R                   R                  [
        R                  :X  a  [        SU R                  R!                  SSU5      S-   5      nU R                  R#                  SU5      S:  a  U R                  R#                  SU5      nO[        U R                  5      S-
  nX4v   gg7f)z
Return a list of (from, to) tuples for the selection or none if nothing
was selected.  start and end position are always included in the
selection.

This will yield several (from, to) tuples in case of a BLOCK selection.
r   r   rb   N)rB   rD  rA   rE  typer   BLOCKr   r-   r   r<   r   r   LINESr   r?   rfindr   )
r   rF  rG  	from_linefrom_columnto_line	to_columnr-   lrr   s
             r   selection_rangesDocument.selection_ranges
  sh     >>> 4 4dnn6]6]^_IE~~""m&9&99)-)I)I%)P&	%)%E%Eb%I")/0H)I&

yA+6A"%eh-K"0#>>qN#>>q#kTUoW`Babd d 7 >>&&-*=*==499??4E#BQ#FGEyy~~dB/14!YY^^D"5 ^a/i1 s   C	F4C%F4c           
         U R                   (       Gad  U R                  US5      nU R                  U[        S[        U R                  U   5      S-
  5      5      n[        U R                  U R                   R                  /5      u  pE[        X$5      n[        X55      nXg::  a  U R                   R                  [        R                  :X  a  UnUnO~U R                   R                  [        R                  :X  aV  U R                  U5      u  pU R                  U5      u  p[        X/5      u  pU R                  X5      nU R                  X5      nU R                  U5      u  pU R                  U5      u  pX4$ gg)zh
If the selection spans a portion of the given line, return a (from, to) tuple.
Otherwise, return None.
r   r   N)rB   r   r   r<   r-   rD  rA   rE  r   rK  r   rM  rL  r   )r   r   	row_startrow_endrF  rG  intersection_startintersection_endrd   col1col2rP  rR  s                r   selection_range_at_line Document.selection_range_at_line,  sT   
 >>>77Q?I55c3q#djjQToBVYZBZ;[\G 4 4dnn6]6]^_IE "%Y!6"7/!5>>&&-*=*==)2&'.$^^((M,?,??">>uEGA">>rBGA!'!5JD)-)H)H)S&'+'F'Fs'Q$!%!A!ABT!U#??@PQ"-- 6 r   c                    U R                   (       Ga   / n/ nU R                  nSnU R                  5        HO  u  pVUS:X  a  UnUR                  U R                  XE 5        UR                  U R                  XVS-    5        US-   nMQ     UR                  U R                  US 5        SR                  U5      nSR                  U5      nU R                   R                  [        R                  :X  a  UR                  S5      (       a  USS n[        XS9[        XpR                   R                  5      4$ U [        S5      4$ )z
Return a (:class:`.Document`, :class:`.ClipboardData`) tuple, where the
document represents the new document when the selection is cut, and the
clipboard data, represents whatever has to be put on the clipboard.
r   r   Nrb   rQ   rW   r[   )rB   rA   rT  r   r?   joinrK  r   rM  endswithr   r
   )	r   	cut_partsremaining_partsnew_cursor_positionlast_torF  rG  cut_textremaining_texts	            r   cut_selectionDocument.cut_selectionK  s*    >>>I O"&"6"6G!224	a<*/'&&tyy'?@  5a!89q& 5 ""499WX#67yy+HWW_5N ~~""m&9&99h>O>OPT>U>U#CR=.V!(NN,?,?@B B r***r   c                    [        U[        5      (       d   eU[        R                  [        R                  [        R
                  4;   d   eU[        R                  :H  nU[        R                  :H  nUR                  [        R                  :X  a  U(       aJ  U R                  SU R                  S-    UR                  U-  -   U R                  U R                  S-   S -   nO)U R                  UR                  U-  -   U R                  -   nU R                  [        UR                  5      U-  -   nU(       a  US-  nGOUR                  [        R                  :X  a  U R                  nU(       am  U R                   SU UR                  /U-  -   U R                   US -   n	SR#                  U	5      n[        SR#                  U R                   SU 5      5      U-   nGOnU R                   SUS-    UR                  /U-  -   U R                   US-   S -   n	[        SR#                  U R                   SUS-    5      5      U-   S-   nSR#                  U	5      nOUR                  [        R$                  :X  a  U R                   SS n	U R                  n
U R&                  U(       a  SOS-   n[)        UR                  R+                  S5      5       HT  u  pX-   nU[        U	5      :  a  U	R-                  S5        X   R/                  U5      X'   X   SU X-  -   X   US -   X'   MV     SR#                  U	5      nU R                  U(       a  SOS-   n[1        WWS9$ )z
Return a new :class:`.Document` instance which contains the result if
we would paste this data at the current cursor position.

:param paste_mode: Where to paste. (Before/after/emacs.)
:param count: When >1, Paste multiple times.
Nr   rb   rQ   r   r[   )r9   r
   r	   	VI_BEFOREVI_AFTEREMACSrK  r   
CHARACTERSr?   rA   r\   r_   r<   rM  rv   r-   r`  rL  r   r   rl   r   ljustr   )r   data
paste_moder   beforeafternew_textrd  rS  r-   
start_linestart_columnr   r   r   s                  r   paste_clipboard_dataDocument.paste_clipboard_datam  s    $....i1193E3EyWWWW	 3 33y11199000 II&?t';';a'?@499uCTT IId&:&:Q&>&?@A  22TYY5FFI_I__"&"6"6TYY%9O"O#q(#YY----((A

2A$))u)<<tzz!"~M99U+&)"''$**Ra.*A&BQ&F#

6AE*dii[5-@@4::aRSefCUU&)"''$**Va!e2D*E&F&JQ&N#99U+YY----JJqME11J33FqJL$TYY__T%:;CJ&LL$$|11,?$|M\:T\IELYeYfLgg < yy'H"&"6"6v!1"MX7JKKr   c                     SnU R                   SSS2    H'  nU(       a  UR                  5       (       a  US-  nM&    U$    U$ )z:
Return number of empty lines at the end of the document.
r   NrW   r   )r-   r   )r   r   r   s      r   empty_line_count_at_the_end$Document.empty_line_count_at_the_end  sE     JJtt$D4<<>>
 % r   c                     S nU R                  X1S9nU(       a(  U(       a  SOSn[        SU R                  U* S9U-   5      $ U R                  * $ )zH
Return the start of the current paragraph. (Relative cursor position.)
c                 >    U (       + =(       d    U R                  5       $ r,   r   r?   s    r   r  /Document.start_of_paragraph.<locals>.match_func      8-t||~-r   r  r   r   r   r   )r  r   r  rA   )r   r   rr  r  
line_indexadds         r   start_of_paragraphDocument.start_of_paragraph  sY    	. 555Y
!1Cq$55ZK5H3NOO((((r   c                     S nU R                  X1S9nU(       a'  U(       a  SOSn[        SU R                  US9U-
  5      $ [        U R                  5      $ )zF
Return the end of the current paragraph. (Relative cursor position.)
c                 >    U (       + =(       d    U R                  5       $ r,   r~  r  s    r   r  -Document.end_of_paragraph.<locals>.match_func  r  r   r  r   r   r  )r  r   r  r<   r_   )r   r   rs  r  r  r  s         r   end_of_paragraphDocument.end_of_paragraph  sY    	. 11Z1U
!!Cq$77j7ICOPPt--..r   c                 Z    [        U R                  U-   U R                  U R                  S9$ )zy
Create a new document, with this text inserted after the buffer.
It keeps selection ranges and cursor position in sync.
r?   rA   rB   )r   r?   rA   rB   )r   r?   s     r   insert_afterDocument.insert_after  s-    
 YY% $ 4 4..* 	*r   c                     U R                   nU(       a*  [        UR                  [        U5      -   UR                  S9n[        XR                  -   U R                  [        U5      -   US9$ )zz
Create a new document, with this text inserted before the buffer.
It keeps selection ranges and cursor position in sync.
)rE  rK  r  )rB   r   rE  r<   rK  r   r?   rA   )r   r?   selection_states      r   insert_beforeDocument.insert_before  sf    
 ..,)8)Q)QTWX\T])]$))+O II% $ 4 4s4y @)+ 	+r   )r7   r5   r6   r4   )rQ   NN)r   )FFFr   )F)FFr   )r   F)FFF)Fr   F)r   )r   Nr,   )NN)Jr   r   r   r   r   	__slots__r0   rH   propertyr?   rA   rB   rT   rX   r\   r_   re   ri   r-   rs   rw   rz   r}   r   rS   r   r   rv   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r  r  r#  r'  r,  r/  r2  r6  r9  r=  rA  rH  rT  r]  rh  r	   rm  rw  rz  r  r  r  r  r'   r   r   r   r   r   D   s   
 FI=HY   % %   : : ; ; 1 1 0 0  
  
 ! ! ( (6 5 5  
 P P
 % % - - ? ?   7 7
!	2 6 6 / /Q IN&' DR,Y& V[DI%
NS,:$0""6?UM0:0: &5:3N
'  D.> +D 5>OO1 4Ll)/"*+r   r   ) r   
__future__r   r   r   r:   r   weakref	six.movesr   r   rB   r   r   r	   	clipboardr
   __all__compiler   r   r   r   r   r   WeakValueDictionaryr>   listr   objectr)   r   r   r   r   <module>r     s    (  	 
     ? ? $
 

>?

#GH 46JJ?h4i 1 JJ{+ JJ|4 8:

?8S 5 "557  &!V !e+v e+r   