VBFj|6dZddlmZddlZddlmZddlmZmZm Z m Z ddl m Z ddl mZdd lmZmZdd lmZmZmZmZmZdd lmZmZdd lmZmZmZGd dejZ Gdde Z!d@dZ"dAd&Z#dBd+Z$dCd0Z%dDd5Z&dCd6Z'd7d8dd9d:dd;d<dEd?Z(dS)Fz*This is a python implementation of clip().) annotationsN)islice)LiteralCallableOptional NamedTuple)width)iter_graphemes) HyperlinkHyperlinkParams)_SGR_STATE_DEFAULT _SGRState_sgr_state_update_sgr_state_is_active_sgr_state_to_sequence) TextSizingTextSizingParams)_SEQUENCE_CLASSIFY_HORIZONTAL_CURSOR_MOVEMENTINDETERMINATE_EFFECT_SEQUENCEceZdZdZejZejZejZejZ dS)_HyperlinkActionz.Outcome of processing an OSC 8 hyperlink unit.N) __name__ __module__ __qualname____doc__enumautoNO_CLOSEEMPTYOUTSIDEVISIBLE;C:\PYTHON\_runtimes\venv\Lib\site-packages\wcwidth/_clip.pyrrsH88ty{{H DIKKEdikkGdikkGGGr%rceZdZUdZded<dZded<dZded<dZd ed <dZd ed <dZ d ed <dZ ded <dZ ded<dS)_HyperlinkResultzn Result of processing an OSC 8 hyperlink. Only the fields relevant to each action are populated. ractionrint close_end inner_widthstropen_seq clipped_inner close_seq clipped_width hl_col_endN) rrrr__annotations__r+r,r/r0r1r2r3r$r%r&r(r("s IKHMIMJr%r(resultr.captured_styleOptional[_SGRState]returnc^|*t|x}r||z}t|r|dz }|S)z Apply SGR prefix/suffix around *result*. If an SGR state was captured at the first visible character, prefix the result with the corresponding SGR sequence and suffix with a reset if any styles are active. Nz)rr)r5r6prefixs r&_apply_sgr_wrapr;3sG!+N;; ;6 %f_F  / / i F Mr%textstartr*endfillchartabsizeambiguous_width term_program bool | str control_codes$Literal['parse', 'strict', 'ignore']paramsr match_endcolc ^tj|| \} } | | fdkrttjS|| | } t | ||||}|dkrttj| S| |z}||ks| |krttj| |Std|| z }|| z }t| ||||||d| }t |||||}ttj | || || ||S) z Process an OSC 8 hyperlink unit. Finds the matching close sequence, measures the inner text width, and determines whether the hyperlink is empty, outside the clip window, or visible (requiring inner-text clipping). )rJ)rDr@rArBr)r+)r+r,F)r?r@rArB propagate_sgrrD)r+r,r/r0r1r2r3) r find_closer(rr r r!r"maxclipr# make_open make_close)r<r=r>r?r@rArBrDrFrGrH close_startr+ inner_textr,r3inner_clip_startinner_clip_endr0r2s r&_process_hyperlinkrUBs*'1$ BBKY8++ 0 9:::i +,J-!K a 0 6)LLLL{"JUcSjj 0 8I,7999 91eck**3YN$n7'!# M]!M  !!#####%%#    r%cellsdict[int, tuple[str, int]] sequenceslist[tuple[int, int, str]]ci}|D]1\}}}||g||f2|D]} | |r!t |nd} |r!t |nd} t | | } g} d}t | |}||kr||dD]\}}| |||kr|dz }C||vr&||\}}| |||z }n*||cxkr| krnn| ||dz }||kt|D]+}||kr#||D]\}}| |,d | S)z Reconstruct the output string from painter's algorithm state. Walks columns left-to-right, interleaving escape sequences and cell content, filling gaps with *fillchar*. rJrr$r r-) setdefaultappendvaluessortrMkeysmingetsortedjoin)rVrXr=r>r? seqs_by_colcol_posorderseq_textentries max_cell_col max_seq_colmax_colpartswalk_col col_limit_ cell_textcell_wcs r&_reconstruct_painterrss#57K$-FF w++22E83DEEEE%%'' (-53uzz||$$$2L-8@#k&&(()))bK, ,,GEHGS!!I i  &??8R88 # #KAx LL " " " " s?? MH  u   %h Iv LL # # #  HH0000L00000 X&&& MH! i  &K$$&& ' ''' y==*1~ ' ' 8 X&&&& 775>>r%rKboolstricttuple[str, Optional[_SGRState]]c  g} d} d} d} |rtnd}| t|kr|| }| |kr,|dvr(| n|d| dz}|dkrn|} N|dkr_tj|| }|s| || dz } |d;|r9|7t||}|} tj |x}r"t|||||||| |||  }|j tjur<| ||} n|j tjur|j} n|j tjur| |jz } |j} ne| |j| |j| |j|r| |} | |jz } |j} "|d x}|d }|d }||Jt-t/j|| ||}||}| |kr<| |z|kr3| ||r| |} | |z } nN| |krC| |z|kr:gdfd }t7|| ||||||} | |r| |} n| |z } |} J|}|r)t;j|rt=d| d|| ||} |dkrj|dkrH| || |zz z}| |kr6|| cxkr|krnn| d|r| |} | dz } | |k6n| d| dz } $t?tA|| }tC|||}|dkr&|| cxkr|krnn| |nz| |kr%| |z|kr| ||r| |} nO| |krI| |z|kr@| |tE|| |ztG|| z z|r| |} | |z } | t|z } | t|kd$| | fS)z Clip text without cursor movement (simple append-to-output path). Returns ``(result, captured_style)``. The caller applies SGR wrapping. rNz  r rJ sgr_paramsrFrGrHts_metats_textts_termrDsr._wr*_colr8Nonec2|dS)N)r\)rrrts_partss r& _ts_writez_clip_simple.._ts_write-s *****r%*Indeterminate cursor sequence at position ,   r=rArBr-)rr.rr*rr*r8r)%rlenfindrmatchr\grouprr>r parserUr)rr r!r+r"r,r/r0r1rr from_params display_width make_sequence_text_sizing_clipextendr ValueErrornextr r r`rMrc)r<r=r>rKrArBr?r@rurDoutputrHidxr6 current_stylecharnext_escmhl_staterr{r|r}tsts_widthrseqnext_tabgrapheme grapheme_wrs @r& _clip_simplers<,F C C+/N*7A&&TM D //Cy #::$n44) yyq11H2~~C  6>>"(s33A  d###qww|$$0]0}G` 1- K K eegg+0;;;x &%h !#quuwwC  8/888MM!'')),,,%%''CCX!1!777+CCX!1!9991=(C+CCMM!*---MM!/222MM!+...$7)?)61=(C+C779---:''),,''),,*w/B/BB$0 VVVW&&++O<<%<E#9#9*,H+++++++CX$!##CMM(+++$7)?)68OCeegg''))C 7=cBB   MM#   %%''C  4<<{{'S7]";<Hnn))))c))))) c***(;^-C-:N1HC Hnn d### 1HC t3777888_(4666  ??!!!!c!!!!! h''' E\\cJ.#55 MM( # # # /!7!. 3YY3+e33 MM(c#sZ/?&@&@3uc??&RS T T T /!7!. z s8}}M D //P 776??N **r%rr write_cellsCallable[[str, int, int], None]c |}||kr-||z|kr$||||zS||ks ||z|kr||zStd||z } t|||z|z } jjg} jjdkrttj jjD]} | | ftjjt| z D]} | dfnAtj D],} | | t | ||zf-gd fd }|| z}d}| D]\}}||z}|| kr|}|| krnt|| t|| z }||kr3|dkr-s|t|| z} ||fn@|||t|| z}t|D]}|d ||z|}||||zS) z Emit tokens for a text-sizing (OSC 66) sequence, clipped to (start, end). Calls *write_cells(text, width, col)* for each emitted cell or sequence. Returns new column position. rr-r flush_colr*r8rcsdSdD}tdD}tjjdkrt |ndjjjjjjjj}t|d |j  || dS)Ncg|] }|d S)rr$.0us r& z4_text_sizing_clip..flush..s---!1---r%c3&K|] }|dV dS)r Nr$rs r& z3_text_sizing_clip..flush..s&22qad222222r%rr-)sumrrFr r numerator denominatorvertical_alignhorizontal_alignrrc terminatorrclear)rtextstotal_wrF pending_unitsscalerrs r&flushz _text_sizing_clip..flushs  F--}---22M22222! )/A--CJJJ1 I !6 I $bi&@ BB  vrwwu~~r} = = K K M M      r%r )rr*r8r) rrrMr`rFrr rr r<r\ranger)rrHr=r>r?rArBrr rel_startrel_endunitsgror flush_col_posunit_pos unit_textunit_wunit_endoverlap abs_startirrs` ` @@r&rrns"00H e||h#-- B$$&&#666X~ czzS8^u,,X~Aus{##I#sX~&&,G IOE#%E yrw//AA % %A LL!U $ $ $ $ryU344 & &A LL"e % % % % & (( ? ?A LLE!_'35557<=> ? ? ? ?,.M )OMH" 6f$ y H  w   Eh((3x+C+CC f  !  ? #c(I&>&> >  )V!4 5 5 5 5 E- c(I666I7^^ 8 8 HaQ7777 E- >r%c  $%&'i%t'g} d} d} d} d$rtnd& d&d'$%&'fd }| t|kr$|| }| |kr $|dkrn |dkrgtj|| }|s)| | | |f| dz } r$&$| dz } s|d;r9&7t&|&|} tj |x}rFt||||||| |||  }|j tjurJ| | | |f| dz } r$&$|} n|j tjur|j} n|j tjur| |jz } |j} n{| | | |jf| dz } r$&$||j|j| d| |jz } | | | |jf| dz } |j} |j} 2|dx}|d}|d}||Jt1t3j|| ||}t7|| |||||} r$&$|} |}|r)t9j|rt;d| d||dx},|rt=|dz nd} |} R|dx}x|rt=|nd}| |z}| |krB||kr._write_cellssXAhh - -F&(G{{uyy1g>>qAQFF&.]gk"''! 444yy'**1-22&.]gk"''! 444 IIgt $ $ $  # #G , , , ,q6i  8(( 8 8##I$67777  +^3*NNN + +33r%rxr ryrzT)rr{r|r}r~rrhpa_n cforward_n cbackward_nz!Cursor left movement at position z would move z cells left from column z, exceeding string start rrr)F) rr.rr*rr*rrtr8r)&setrrrrr\rrr>r rrUr)rr r!r+r"r,r/r0r2r1r3rrrrrrr*rrMr`rr r rs)(r<r=r>rKrArBr?r@rurDrX seq_orderrHrrrrrrr{r|r}rrrr n_forwardmove_endrr n_backwardrrr clip_startrr6rVrrs( ` ` @@@@r& _clip_painterrst,)+E #O,.II C C+/N*7A&&TM+0++++++++++++* D //Cy #::.4  6>>"(s33A   #y$!7888Q  3^%;%2Nqww|$$0]0}G` 1- K K eegg+0;;;x &%h !#quuwwC  8/888$$c9aggii%@AAANI$7)?)6%%''CCX!1!777+CCX!1!9991=(C+CC$$c9aj%ABBBNI$7)?)6 L!/3.244441?*C$$c9ak%BCCCNI,C+C779---:''),,''),,*w/B/BB$0 VVVW&&(UC?  ""!3^%;%2Neegg''))C 7=cBB   )))6(-4c%jj1nn1eegg ggl333 @/9@C OOOq ?99E!1!1"3sE??C#4F4FGG55$ Xq!4444eegg !ww}555 B1<CS---! j3..$2C22%22?B222 z!77Ceegg   c9aggii8 9 9 9 NI /!7!.%%''C  4<<C 1HC  6>>Qwwq 1HC  4<<{{'S7]";<Hnn))))c)))))$ Xq#6661HCHnn   #y$!7888Q  3^%;%2N 1HC t3777888_(4666  ??!!!!c!!!!!  #y(!;<<<Q  3^%;%2N E\\cJ.#55 L:s 3 3 3 3 3YY3+e33UCJCz)9 : :Z GHH ? ? Xq*v*=>>>> z s8}}W D //Z y%h G G WWr%rTrF)r?r@rArKrD overtypingrBrOptional[bool]ct|d}||krdS|r|r |||Sd|v} |r| sd}|2|dko*d|vp&d|vp"| o tt j|}n |r|dkrd}|rt nt} t| |||||| |||d k| S) ua Clip text to display columns (start, end) while preserving all terminal sequences. This function extracts a substring based on visible column positions rather than character indices. Terminal escape sequences are preserved in the output since they have zero display width. If a wide character (width 2) is split at either boundary, it is replaced with ``fillchar``. TAB characters (``\t``) are expanded to spaces up to the next tab stop, controlled by the ``tabsize`` parameter. When cursor movement is detected, a "painter's algorithm" is used, cursor movements actively change the write position, allowing cursor-left and carriage return to overwrite previously written cells. It is assumed that ``text`` begins at column 0. **OSC 8 hyperlinks** are handled specially: the visible text inside a hyperlink is clipped to the requested column range, and the hyperlink is rebuilt around the clipped text. Empty hyperlinks (those with no remaining visible text after clipping) are removed:: >>> clip('\x1b]8;;http://example.com\x07Click This link\x1b]8;;\x07', 6, 10) '\x1b]8;;http://example.com\x07This\x1b]8;;\x07' :param text: String to clip, may contain terminal escape sequences. :param start: Absolute starting column (inclusive, 0-indexed). :param end: Absolute ending column (exclusive). :param fillchar: Character to use when a wide character must be split at a boundary (default space). Must have display width of 1. :param tabsize: Tab stop width (default 8). Set to 0 to pass tabs through as zero-width (preserved in output but don't advance column position). :param ambiguous_width: Width to use for East Asian Ambiguous (A) characters. Default is ``1`` (narrow). Set to ``2`` for CJK contexts. :param propagate_sgr: If True (default), SGR (terminal styling) sequences are propagated. The result begins with any active style at the start position and ends with a reset sequence if styles are active. :param control_codes: How to handle control characters and sequences: - ``'parse'`` (default): Track horizontal cursor movement and clip hyperlink text. Cursor overwrite is always allowed, with best effort results; indeterminate sequences (home, clear, reset, etc.) are preserved as zero-width. - ``'strict'``: Like ``parse``, but raises :exc:`ValueError` on sequences with indeterminate effects (cursor home, clear screen, reset, vertical movement, etc.) matching :func:`width` behavior. Also raises on out-of-bounds horizontal cursor movement. - ``'ignore'``: All control characters are treated as zero-width. Cursor movement is not tracked (fastest path). :param overtyping: Whether to use the painter's algorithm for cursor movement (``\b`` backspace, ``\r`` carriage return, and CSI cursor left/right/position sequences). When ``None`` (default), auto-detects by scanning for these characters in *text*. Set to ``False`` for improved performance when the caller knows *text* contains no cursor movement characters. Set to ``True`` to force the painter's algorithm (useful for testing). Has no effect when ``control_codes='ignore'``. :param term_program: Terminal software identifier for table correction. ``False`` (default) disables override lookup. ``True`` reads the ``TERM_PROGRAM`` or ``TERM`` environment variable for auto-detection. Accepts a canonical terminal name matching :func:`list_term_programs`, such as from XTVERSION_, ENQ_, or ``TERM_PROGRAM``. .. versionadded:: 0.8.0 :returns: Substring of ``text`` spanning display columns (start, end), with all terminal sequences preserved and wide characters at boundaries replaced with ``fillchar``. :raises ValueError: If ``control_codes='strict'`` and an indeterminate-effect sequence or out-of-bounds cursor movement is encountered. SGR (terminal styling) sequences are propagated by default. The result begins with any active style and ends with a reset:: >>> clip('\x1b[1;34mHello world\x1b[0m', 6, 11) '\x1b[1;34mworld\x1b[0m' Set ``propagate_sgr=False`` to disable this behavior. .. versionadded:: 0.3.0 .. versionchanged:: 0.5.0 Added ``propagate_sgr`` parameter (default True). .. versionchanged:: 0.7.0 Added ``control_codes`` parameter (default 'parse'). OSC 8 hyperlink-aware clipping. OSC 66 text sizing protocol support. Added ``overtyping`` parameter (default None, auto-detect). Example:: >>> clip('hello world', 0, 5) 'hello' >>> clip('中文字', 0, 3) # Wide char split at column 3 '中 ' >>> clip('a\tb', 0, 10) # Tab expanded to spaces 'a b' rr-rxFNignorerrru) r<r=r>rKrArBr?r@rurD) rMisascii isprintablertrsearchrrr;) r<r=r>r?r@rArKrDrrBhas_escfn_clips r&rNrNs0Z qMME e||r ||~~$**,,E#InGW  X % K t^Jtt|JH$:A$GGHH   11 );mm|G GG  #'!)#     r%)r5r.r6r7r8r.)r<r.r=r*r>r*r?r.r@r*rAr*rBrCrDrErFr rGr*rHr*r8r() rVrWrXrYr=r*r>r*r?r.r8r.)r<r.r=r*r>r*rKrtrAr*rBrCr?r.r@r*rurtrDrEr8rv)rrrHr*r=r*r>r*r?r.rAr*rBrCrrr8r*)r<r.r=r*r>r*r?r.r@r*rAr*rKrtrDrErrrBrCr8r.))r __future__rr itertoolsrtypingrrrr_widthr rr hyperlinkr r sgr_staterrrrr text_sizingrrescape_sequencesrrrEnumrr(r;rUrsrrrrNr$r%r&rs\00"""""" ::::::::::::$$$$$$1111111100000000000000 65555555>>>>>>>>>> tyz"    CCCCL4444nl+l+l+l+^UUUUpiXiXiXiXb:A!%$QQQQQQQQr%