qBFj# dZddlmZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl m Z ddl mZddlmZddlmZmZmZmZmZmZdd lmZdd lmZdd lmZmZdd lm Z dd l!m"Z"ddl#m$Z$m%Z%m&Z&m'Z'm(Z(ddl)m*Z*ddl+m,Z,ddl-m.Z.m/Z/ddl0m1Z1m2Z2ddl3m4Z4m5Z5ddl6m7Z7m8Z8m9Z9ddl:m;Z;mZ>m?Z?gdZ@ejAeBZCGddeDZEGddeZFGddZGejHdZIGdd ZJed!gdfZKed!geLfZMGd"d!ZNed#ed$eeedff%ZOd4d(ZPGd)d*eDZQd5d6d1ZRd5d6d2ZSd7d3ZTdS)8zU Data structures for the Buffer. It holds the text, cursor position, history, etc... ) annotationsN)deque)Enum)wraps)AnyCallable CoroutineIterableTypeVarcast)get_app)run_in_terminal) AutoSuggest Suggestion) FastDictCache) ClipboardData) CompleteEvent Completer CompletionDummyCompleterget_common_complete_suffix)Document)aclosing) FilterOrBool to_filter)HistoryInMemoryHistory)SearchDirection SearchState) PasteModeSelectionState SelectionType)Eventto_str)ValidationError Validator)EditReadOnlyBufferBufferCompletionStateindentunindent reshape_textceZdZdZdS)r(z.Attempt editing of read-only :class:`.Buffer`.N__name__ __module__ __qualname____doc__CC:\PYTHON\_runtimes\venv\Lib\site-packages\prompt_toolkit/buffer.pyr(r(6s4444r5r(ceZdZdZdZdZdZdS)ValidationStatezCThe validation state of a buffer. This is set after the validation.VALIDINVALIDUNKNOWNN)r0r1r2r3r9r:r;r4r5r6r8r8:s#II EGGGGr5r8cPeZdZdZ ddd Zdd ZddZddZeddZ dS)r*z; Immutable class that contains a completion state. Noriginal_documentr completionslist[Completion] | Nonecomplete_index int | NonereturnNonec4||_|pg|_||_dSN)r=r>r@)selfr=r>r@s r6__init__zCompletionState.__init__Gs+"3',"-r5strcj|jjd|jdt|jd|jdS)N(z, completions, index=)) __class__r0r=lenr>r@rFs r6__repr__zCompletionState.__repr__Xsb.)PPD,BPPTM]I^I^PPw{xKPPP Pr5indexcp|jr.|#d|cxkrt|jksnJ||_dSdS)z Create a new :class:`.CompletionState` object with the new index. When `index` is `None` deselect the completion. Nr)r>rMr@rFrPs r6 go_to_indexzCompletionState.go_to_index[s[   (=A$F$F$F$FT5E1F1F$F$F$F$F$FF"'D    ( (r5tuple[str, int]c8|j|jj|jjfS|jj}|jj}|j|j}|jdkr|}n|d|j}||jz|z}t|t|jz}||fS)zM Return (new_text, new_cursor_position) for this completion. Nr) r@r=textcursor_positiontext_before_cursortext_after_cursorr>start_positionrM)rForiginal_text_before_cursororiginal_text_after_cursorcbeforenew_textnew_cursor_positions r6new_text_and_positionz%CompletionState.new_text_and_positiones   &).0F0VV V*.*@*S ')-)?)Q & !45A1$$445Gq7G5GH)CCH"%f++AF "; 00 0r5Completion | Nonec8|j|j|jSdS)zi Return the current completion, or return `None` when no completion is selected. N)r@r>rNs r6current_completionz"CompletionState.current_completionys#   *#D$78 8tr5)NN)r=rr>r?r@rArBrCrBrHrPrArBrC)rBrT)rBrb) r0r1r2r3rGrOrSrapropertyrdr4r5r6r*r*Bs04%) -----"PPPP((((1111(Xr5r*z(\s+|".*?"|'.*?')c&eZdZdZ ddd Zdd ZdS)YankNthArgStatezT For yank-last-arg/yank-nth-arg: Keep track of where we are in the history. rhistory_positionintnprevious_inserted_wordrHrBrCc0||_||_||_dSrE)rlrorn)rFrlrnros r6rGzYankNthArgState.__init__s!1&<#r5cP|jjd|jd|jd|jdS)Nz(history_position=z, n=z, previous_inserted_word=rK)rLr0rlrnrorNs r6rOzYankNthArgState.__repr__s_.)^^T=R^^Z^Z`^^~B~Y^^^ ^r5N)rrjrk)rlrmrnrmrorHrBrCre)r0r1r2r3rGrOr4r5r6ririsX UW^^^^^^r5rir)ceZdZdZ ddd(Zdd)Z ddd,Zdd-Zdd/Zdd0Z e dd1Z e j dd2Z e dd3Z e j dd4Z e dd5Zej dd6Zdd7Zdd8Ze dd:Zej dd;Zddd=Ze dd>Zddd@ZddEZddFZddIZdddLZdddMZdddNZdddOZ dddQZ dddRZdddSZdddTZdddWZ dddXZ!ddYZ"dd[Z#ddd]Z$ ddd^Z%dd_Z&ddcZ'dddZ(ddfZ)ddiZ*ddjZ+ddlZ,dddmZ-dddnZ.dddqZ/dddrZ0e1j2fdduZ3dddxZ4ddyZ5e6j7dJfdd}Z8dddZ9dddZ:dddZ; dddZdddZ?ddZ@ddZA dddZBddZC dddZD dddZEddZFddZGddZHdddZIddZJ dddZKddZLddZMddZNddZOdS)r)a The core data structure that holds the text and cursor position of the current input line and implements all text manipulations on top of it. It also implements the history, undo stack and the completion state. :param completer: :class:`~prompt_toolkit.completion.Completer` instance. :param history: :class:`~prompt_toolkit.history.History` instance. :param tempfile_suffix: The tempfile suffix (extension) to be used for the "open in editor" function. For a Python REPL, this would be ".py", so that the editor knows the syntax highlighting to use. This can also be a callable that returns a string. :param tempfile: For more advanced tempfile situations where you need control over the subdirectories and filename. For a Git Commit Message, this would be ".git/COMMIT_EDITMSG", so that the editor knows the syntax highlighting to use. This can also be a callable that returns a string. :param name: Name for this buffer. E.g. DEFAULT_BUFFER. This is mostly useful for key bindings where we sometimes prefer to refer to a buffer by their name instead of by reference. :param accept_handler: Called when the buffer input is accepted. (Usually when the user presses `enter`.) The accept handler receives this `Buffer` as input and should return True when the buffer text should be kept instead of calling reset. In case of a `PromptSession` for instance, we want to keep the text, because we will exit the application, and only reset it during the next run. :param max_number_of_completions: Never display more than this number of completions, even when the completer can produce more (limited by default to 10k for performance). Events: :param on_text_changed: When the buffer text changes. (Callable or None.) :param on_text_insert: When new text is inserted. (Callable or None.) :param on_cursor_position_changed: When the cursor moves. (Callable or None.) :param on_completions_changed: When the completions were changed. (Callable or None.) :param on_suggestion_set: When an auto-suggestion text has been set. (Callable or None.) Filters: :param complete_while_typing: :class:`~prompt_toolkit.filters.Filter` or `bool`. Decide whether or not to do asynchronous autocompleting while typing. :param validate_while_typing: :class:`~prompt_toolkit.filters.Filter` or `bool`. Decide whether or not to do asynchronous validation while typing. :param enable_history_search: :class:`~prompt_toolkit.filters.Filter` or `bool` to indicate when up-arrow partial string matching is enabled. It is advised to not enable this at the same time as `complete_while_typing`, because when there is an autocompletion found, the up arrows usually browse through the completions, rather than through the history. :param read_only: :class:`~prompt_toolkit.filters.Filter`. When True, changes will not be allowed. :param multiline: :class:`~prompt_toolkit.filters.Filter` or `bool`. When not set, pressing `Enter` will call the `accept_handler`. Otherwise, pressing `Esc-Enter` is required. NrkFT' completerCompleter | None auto_suggestAutoSuggest | NonehistoryHistory | None validatorValidator | Nonetempfile_suffixstr | Callable[[], str]tempfilenamerHcomplete_while_typingrvalidate_while_typingenable_history_searchdocumentDocument | Noneaccept_handlerBufferAcceptHandler | None read_only multilinemax_number_of_completionsrmon_text_changedBufferEventHandler | Noneon_text_inserton_cursor_position_changedon_completions_changedon_suggestion_setrBrCct| } t|}t| } t| } t|}|p t|_||_||_||_||_||_| |_||_ | |_ | |_ | |_ ||_ ||_d|_|t!n||_d|_t'|||_t'|||_t'|||_t'|||_t'|||_t3t4d|_||_||_| |_!d|_"|#| dS)Nr )size)r)$rrrtrvrzr|r~rrrrrrrr text_widthrrx_Buffer__cursor_positionr$rrrrrrr_document_cache_create_auto_suggest_coroutine_async_suggester_create_completer_coroutine_async_completer_create_auto_validate_coroutine_async_validator_load_history_taskreset)rFrtrvrxrzr|r~rrrrrrrrrrrrrrs r6rGzBuffer.__init__s0!**? @ @ )*? @ @ )*? @ @i(( i(( "6n&6&6(".   ,&;"%:"%:""")B& -4O((( !"/4D/.J.J-24-H-H9> ,: : '6;4AW5X5X#05d)rMrVrid)rFrVs r6rOzBuffer.__repr__(s[ ty>>B  9DD9SbS>E)DMtyMM4MM4MMMMr5append_to_historyboolc|r||p t}|j|_d|_t j|_d|_g|_ d|_ d|_ d|_ d|_ d|_d|_g|_g|_|j|jd|_t)|jg|_d|_dS)zR :param append_to_history: Append current input to history first. Nr)rrrWrvalidation_errorr8r;validation_stateselection_statemultiple_cursor_positionspreferred_columncomplete_stateyank_nth_arg_statedocument_before_paste suggestionhistory_search_text _undo_stack _redo_stackrcancelrrV_working_lines_Buffer__working_index)rFrrs r6rz Buffer.reset0s  %  " " $ $ $)xzz!)!99=8G8O7; 57&-17;;?7;".204 3524  " .  # * * , , ,"&+0*@*@ r5cjTdfd }t|_d d}j|dSdS) a Create task for populating the buffer history (if not yet done). Note:: This needs to be called from within the event loop of the application, because history loading is async, and we need to be sure the right event loop is active. Therefor, we call this method in the `BufferControl.create_content`. There are situations where prompt_toolkit applications are created in one thread, but will later run in a different thread (Ptpython is one example. The REPL runs in a separate thread, in order to prevent interfering with a potential different event loop in the main thread. The REPL UI however is still created in the main thread.) We could decide to not support creating prompt_toolkit objects in one thread and running the application in a different thread, but history loading is the only place where it matters, and this solves it. NrBrCcKj23d{V}j|xjdz c_26dS)Nr )rxloadr appendleftr)itemrFs r6 load_historyz;Buffer.load_history_if_not_yet_loaded..load_historysv"&,"3"3"5"5.......$'224888((A-(((#6"5"5sAfasyncio.Future[None]c |dS#tj$rYdSt$rYdSt$rt dYdSwxYw)z Handle `load_history` result when either done, cancelled, or when an exception was raised. zLoading history failedN)resultasyncioCancelledError GeneratorExit BaseExceptionlogger exception)rs r6load_history_donez@Buffer.load_history_if_not_yet_loaded..load_history_dones ?HHJJJJJ-DD$DD$???$$%=>>>>>>?sA A#AArBrC)rrrBrC)rrcreate_background_taskadd_done_callback)rFrrs` r6load_history_if_not_yet_loadedz%Buffer.load_history_if_not_yet_loadedqs*  " * . . . . . . '.ii&F&F||~~&V&VD # ? ? ? ?*  # 5 56G H H H H H= + *r5valuec|j}|j}||}|||<t|t|krdS||krdSdS)z=set text at current working_index. Return whether it changed.TF) working_indexrrM)rFrr working_linesoriginal_values r6 _set_textzBuffer._set_texts]* + &}5', m$ u::^,, , , 4 n $ $4ur5cP|j}td||_|j|kS)z/Set cursor position. Return whether it changed.r)rmax)rFroriginal_positions r6_set_cursor_positionzBuffer._set_cursor_positions* 2!$Q%):::r5c&|j|jSrE)rrrNs r6rVz Buffer.texts"4#566r5c |jt|krt||_|rt||}|r|d|_dSdS)z Setting text. (When doing this, make sure that the cursor_position is valid for this text. text/cursor_position should be consistent at any time, otherwise set a Document instead.) N)rWrMrr(r _text_changedrrFrchangeds r6rVz Buffer.texts  #e** , ,#&u::D  >>   '$&& &..''  ,    (,D $ $ $ , ,r5c|jSrE)rrNs r6rWzBuffer.cursor_positions %%r5ct|tsJ|t|jkrt|j}|dkrd}||}|r|dSdS)z* Setting cursor position. rN) isinstancermrMrVr_cursor_position_changedrs r6rWzBuffer.cursor_positions %%%%%% 3ty>> ! ! NNE 199E++E22  ,  ) ) + + + + + , ,r5c|jSrE)rrNs r6rzBuffer.working_indexs ##r5cd|j|kr$||_d|_|dSdS)Nr)rrWrrFrs r6rzBuffer.working_indexsB  5 ( (#(D $%D    ) (r5c`d|_tj|_d|_d|_d|_d|_d|_d|_ |j |j rI| r7t|dSdSdSrE)rr8r;rrrrrrrrfirerzrrrrrNs r6rzBuffer._text_changeds $ / 7""&%)"# $ !!### > Fd88:: F II , ,T-B-B-D-D E E E E E F F F Fr5cpd|_d|_d|_d|_|jdSrE)rrrrrrrNs r6rzBuffer._cursor_position_changedsC#"&%)"!% ',,.....r5rc@|j|j|j|jfS)z Return :class:`~prompt_toolkit.document.Document` instance from the current text, cursor position and selection state. )rrVrWrrNs r6rzBuffer.document+s& # It+T-A A  r5c0||dS)z Set :class:`~prompt_toolkit.document.Document` instance. This will set both the text and cursor position at the same time, but atomically. (Change events will be triggered only after both have been set.) N) set_documentrs r6rzBuffer.document5s %     r5bypass_readonlyc |s"|rt||j}||j}|r|d|_|r|dSdS)a3 Set :class:`~prompt_toolkit.document.Document` instance. Like the ``document`` property, but accept an ``bypass_readonly`` argument. :param bypass_readonly: When True, don't raise an :class:`.EditReadOnlyBuffer` exception, even when the buffer is read-only. .. warning:: When this buffer is read-only and `bypass_readonly` was not passed, the `EditReadOnlyBuffer` exception will be caught by the `KeyProcessor` and is silently suppressed. This is important to keep in mind when writing key bindings, because it won't do what you expect, and there won't be a stack trace. Use try/finally around this function if you need some cleanup code. N) rr(rrVrrWrrr)rFrr text_changedcursor_position_changeds r6rzBuffer.set_document?s& '4>>#3#3 '$&& &~~ej11 "&";";E III  r5c |jsJt|j|jjg\}}|jd|}|j||}|j|d}fd|D}t |d|z|zt|d|ddzdz |_ dS)z* Join the selected lines. Nc@g|]}|dzSr*)r.).0lr+s r6 z.Buffer.join_selected_lines..As(:::q#*:::r5rkrjr rVrW) rsortedrWoriginal_cursor_positionrV splitlinesrrrMr)rFr+rrr^rafters ` r6join_selected_lineszBuffer.join_selected_lines1s####  !4#7#P Q  r6E6" %(#..00 "##;:::E:::!"''%..(50ss)<)< <==A    r5c|j}|dkrO|j|dz }|j|dz }|jd|dz |z|z|j|dz|_dSdS)zA Swap the last two characters before the cursor. r N)rWrV)rFposrrs r6swap_characters_before_cursorz$Buffer.swap_characters_before_cursorIso" !88 #'"A #'"A )C!G),q014tyFDIII 8r5rPcz|t|jkr"||_t|j|_dSdS)z1 Go to this item in the history. N)rMrrrVrWrRs r6 go_to_historyzBuffer.go_to_historyUs@ 3t*++ + +!&D #&ty>>D  , +r5disable_wrap_aroundc|jryt|jj}|jjd}n:|jj|dz krd}|rdSn t |dz |jj|z}||dSdS)zd Browse to the next completions. (Does nothing if there are no completion.) Nrr )rrMr>r@mingo_to_completion)rFrrBcompletions_countrPs r6r!zBuffer.complete_next]s   ) #D$7$C D D "19$37H17LLL&F%)4+>+MPU+U  ! !% ( ( ( ( ( ) )r5c|jrt|jjdkrd}|rdSnF|jjt|jjdz }nt d|jj|z }||dSdS)zh Browse to the previous completions. (Does nothing if there are no completion.) rNr )rr@rMr>rrE)rFrrBrPs r6rzBuffer.complete_previousts   )"1Q66&F$3;D/;<list[Completion]r*cxt|j||_|j|jS)z Start completions. (Generate list of completions and initialize.) By default, no completion will be selected. )r=r>)r*rrrr)rFr>s r6_set_completionszBuffer._set_completionssB ."m    #((***""r5c t}g}|jj}t |jD]\}}t |dD]\}}|}|r||rn||vrj| |||j kr d|dzz}nd|dzd|dz}| t|t| |||ddd |d dS) zj Start a completion based on all the other lines in the document and the history. rzCurrent, line %sr zHistory z, line )rVrZ display_metaNrjr>r)setrcurrent_line_before_cursorr. enumeraterrstrip startswithaddrrrrMrLrE) rFfound_completionsr> current_lineistringjr4rNs r6start_history_lines_completionz%Buffer.start_history_lines_completionsw '*ee }?FFHH "4#677  IAv!&,,t"4"455  1GGIIl33 111)--a000 222+=Q+GLL+Ka!e+K+KAE+K+KL#**&%&03L0A0A/A-9 * +ddd*;<<< a     r5rAc|jsJ|j}|||\}}t|||_||_dS)zK Select a completion from the list of current completions. N)rrSrarr)rFrPstater_r`s r6rEzBuffer.go_to_completionsl""""# %   ).(C(C(E(E%% +>?? $r5 completionrc|jr|dd|_||j ||jdS)z, Insert a given completion. N)rrEr'rZ insert_textrV)rFr^s r6apply_completionzBuffer.apply_completionsc   (  ! !$ ' ' '" !!:#<"<=== )))))r5ct|r|j|jj|_dSdSd|_dS)zy Set `history_search_text`. (The text before the cursor will be used for filtering the history.) N)rrrrXrNs r6_set_history_searchzBuffer._set_history_searchsL  % % ' ' ,'/+/=+K(((0/(,D $ $ $r5rXc^|jdup$|j||jS)z True when the current entry matches the history search. (when we don't have history search, it's also True.) N)rrrT)rFrXs r6_history_matcheszBuffer._history_matchess9 '4/ 43Fq3I3T3T  $4 4  r5cF|d}t|jdzt|jD]-}||r||_|dz}d}|dkrn.|r0d|_|xj|jz c_dSdS)zl Move forwards through the history. :param count: Amount of items to move forward. Fr TrN) rcrangerrMrrerWrrrFrfound_somethingrXs r6r#zBuffer.history_forwards   """ t)A-s43F/G/GHH  A$$Q'' '%&" "&zz  M#$D  DM$J$J$L$L L  M Mr5c|d}t|jdz ddD]-}||r||_|dz}d}|dkrn.|rt |j|_dSdS)z1 Move backwards through history. Fr rjTrN)rcrgrrerMrVrWrhs r6rzBuffer.history_backwards   """ t)A-r266  A$$Q'' '%&" "&zz  2#&ty>>D  2 2r5rn_yank_last_argc|t|tsJ|j}t |sdS|jt |rdnd}n|j}|||_|jdz }| t |krd}||}dt |D}d|D} ||j}n#t$rd}YnwxYw|j r'| t |j ||||_ ||_||_dS)ay Pick nth word from previous history entry (depending on current `yank_nth_arg_state`) and insert it at current position. Rotate through history if called repeatedly. If no `n` has been given, take the first argument. (The second word.) :param n: (None or int), The index of the word from the previous line to take. Nrjr )rnc6g|]}|Sr4)rSr3ws r6r5z'Buffer.yank_nth_arg..Es AAAqAAAr5cg|]}||Sr4r4rns r6r5z'Buffer.yank_nth_arg..Fs'''qQ''''r5rk)rrmrx get_stringsrMrrirnrl_QUOTED_WORDS_RErrror'r`) rFrnrkhistory_stringsr]new_poslinewordswords r6 yank_nth_argzBuffer.yank_nth_arg$syJq#..yy.,2244?##  F  " *#N&AbbBBBEE+E =EG(1, 8c/** * *Gw'AA$4$:$:4$@$@AAA''E''' >DD   DDD   ' I  % %c%*F&G&G H H H (,$!("'s C C&%C&c4||ddS)zp Like `yank_nth_arg`, but if no argument has been given, yank the last word by default. T)rnrkN)rx)rFrns r6 yank_last_argzBuffer.yank_last_argWs# Ad33333r5selection_typer#c:t|j||_dS)zR Take the current cursor position as the start of this selection. N)r"rWr)rFr{s r6start_selectionzBuffer.start_selection^s .d.BNSSr5_cutrc^|j\}}|r||_d|_|S)a8 Copy selected text and return :class:`.ClipboardData` instance. Notice that this doesn't store the copied data on the clipboard yet. You can store it like this: .. code:: python data = buffer.copy_selection() get_app().clipboard.set_data(data) N)r cut_selectionr)rFr~ new_documentclipboard_datas r6copy_selectionzBuffer.copy_selectionfs9(,}'B'B'D'D$ n  )(DM#r5c.|dS)zS Delete selected text and return :class:`.ClipboardData` instance. T)r~)rrNs r6rzBuffer.cut_selectionys"""---r5data paste_moder!ct|tsJ|tjtjtjfvsJ|j}|j||||_||_dS)z5 Insert the data from the clipboard. )rrN) rrr! VI_BEFOREVI_AFTEREMACSrpaste_clipboard_datar)rFrrrr=s r6rzBuffer.paste_clipboard_datasw$ .....i193EyWWWWW M :: Zu;   &7"""r5 copy_marginc||r$|d|jjzdS|ddS)z? Insert a line ending at the current position. rN)r`r"leading_whitespace_in_current_line)rFrs r6newlinezBuffer.newlinesJ  #   TDM$TT U U U U U   T " " " " "r5c|r|jjdz}nd}|xj|jz c_|||xjdzc_dS)z: Insert a new line above the current one. rr N)rrrWrr`rFrinserts r6insert_line_abovezBuffer.insert_line_abovesr  ]ELFFF  H H J JJ     !r5c|rd|jjz}nd}|xj|jz c_||dS)z: Insert a new line below the current one. rN)rrrWrr`rs r6insert_line_belowzBuffer.insert_line_belows^  DMLLFFF  F F H HH      r5 overwrite move_cursor fire_eventc|j}|j}|rd|||t|z}d|vr|d|d}|d||z||t|zdz}n|d||z||dz}|r|jt|z} n|j} t || |_|r|j|jrG| r3t | |j r7t |dSdSdS)z Insert characters at cursor position. :param fire_event: Fire `on_text_insert` event. This is mainly used to trigger autocompletion while typing. rN)rVrWrMfindrrrrrtrrrrrvr) rFrrrrotextocposoverwritten_textrVcposs r6r`zBuffer.insert_texts $  8 %UUSYY->%>? '''#34Q6F6K6KD6Q6Q4Q#R %=4'%"> J 001F1F1H1HIII  J 001F1F1H1HIIIII J J J Jr5c|jrn|j\}}||jkr>|j|j|jft |||_dS|jldSdS)NrW)rpoprVrrrWrrrFrVr>s r6undoz Buffer.undos  (,,..ID#ty   ''D4H(IJJJ!)s C C C      r5c|jrJ|d|j\}}t|||_dSdS)NF)rr)rrrrrrs r6redoz Buffer.redosc   @  # #U # ; ; ;(,,..ID#$T3???DMMM  @ @r5 set_cursorc|jtjkr|jtjkS|jr |j|jnl#t$r_}|r:ttd|j t|j |_ tj |_||_Yd}~dSd}~wwxYwtj|_d|_dS)zv Returns `True` if valid. :param set_cursor: Set the cursor position, if an error was found. rNFT)rr8r;r9rzvalidaterr&rDrrWrMrVr:r)rFres r6rzBuffer.validates  O$; ; ;(O,AA A >  '' 6666"   +.Aq0113ty>>,,D()8(?%()%uuuuu !0 5 $tsA B<AB77B<cK |jtjkrdSd}|j}|jrL |j|jd{Vn#t $r }|}Yd}~nd}~wwxYw|j|krt|rtj|_ntj|_||_ t )a Asynchronous version of `validate()`. This one doesn't set the cursor position. We have both variants, because a synchronous version is required. Handling the ENTER key needs to be completely synchronous, otherwise stuff like type-ahead is going to give very weird results. (People could type input while the ENTER key is still processed.) An asynchronous version is required if we have `validate_while_typing` enabled. TN) rr8r;rrzvalidate_asyncr&r:r9rr invalidate)rFerrorrrs r6_validate_asynczBuffer._validate_async"s #$(???E}H~ .77 FFFFFFFFFF&EEEEEE=H,, >(7(?%%(7(=%$)D ! II " " "7 #s%A A(A##A(c|jrZ|j}t|r|d|jkr#|j|jdSdSdS)z: Append the current input to the history. rjN)rVrxrqrM append_string)rFrss r6rzBuffer.append_to_historyLsp 9 6"l6688O'' 6?2+>$)+K+K **4955555 6 6+K+Kr5 search_stater include_current_positiontuple[int, int] | Nonec |dksJ|j |j | d  fd }j}j}t |D]}|||}|d S|\}}||jfS) z Execute search. Return (working_index, cursor_position) tuple when this search is applied. Returns `None` when this text cannot be found. rrrmrrrBtuple[int, Document] | Nonec|tjkr|}||t|j|j|zfSt |dztjdzD]g}|tjz}tj|d}|d}||t|j|fcShn| }||t|j|j|zfSt |dz ddD]}|tjz}tj|tj|}| }|.|t|jt|j|zfcSdS) zd Do search one time. Return (working_index, document) or `None` )r ignore_caseNr rT)rrj) rFORWARDrrrVrWrgrMrfind_backwards) rr new_indexrX directionrrrFrVs r6 search_oncez#Buffer._search..search_oncegsO333$MM-E +* (% 0H90TUU#=1#4c$:M6N6NQR6RSSKKS!4555#+D,?,BA#F#F$,MM 4[%2%% %0$%x y'I'I#JJJJ1K%33Dk3RR (% 0H90TUU #=1#4b"==  S!4555#+ /2C8KA8N4O4O$$%-$;$; k%<%% %0 ! (HM8J8JY8V W W$1 4r5N)rrmrrrBr)rVrrrrrgrW) rFrrrrrr_rrrrVs ` ` @@@r6_searchzBuffer._searchWsqyyyy  * "..00 : : : : : : : : : : z* =u 1 1A [99F~tt*0' xxx788r5c||d}||jS|\}}||jkr|j}nd}t |j|||S)a# Return a :class:`~prompt_toolkit.document.Document` instance that has the text/cursor position for this search, if we would apply it. This will be used in the :class:`~prompt_toolkit.layout.BufferControl` to display feedback while searching. T)rN) selection)rrrrrr)rFr search_resultrrWrs r6document_for_searchzBuffer.document_for_searchsv \D QQ  = -: *M? 222 0  #M2Oy r5cR||||}||jS|\}}|S)z Get the cursor position for this search. (This operation won't change the `working_index`. It's won't go through the history. Vi text objects can't span multiple items.) rr)rrWrFrrrrrrWs r6get_search_positionzBuffer.get_search_positionsF 3KSX%    ' '-: *M?" "r5cd||||}||\}}||_||_dSdS)zi Apply search. If something is found, set `working_index` and `cursor_position`. rN)rrrWrs r6 apply_searchzBuffer.apply_searchsU 3KSX%    $-: *M?!.D #2D  % $r5cd|_dSrE)rrNs r6exit_selectionzBuffer.exit_selections#r5tuple[str, Callable[[], None]]ct|j}tj|\}t j||jdt j|dfd }|fS)za Simple (file) tempfile implementation. Return (tempfile, cleanup_func). utf-8rBrCc0tjdSrE)osunlink)filenamesr6cleanupz/Buffer._editor_simple_tempfile..cleanups Ih     r5r) r%r|r~mkstemprwriterVencodeclose)rFsuffix descriptorrrs @r6_editor_simple_tempfilezBuffer._editor_simple_tempfiles ,--'/77 H TY--g66777         r5czt|j}|s|St|}tj|\}}tj|r |dd}tj|r tj |t j tj |}t|dd5}| |j dddn #1swxYwYdfd }||fS) Nr ror)encodingrBrCc0tjdSrE)shutilrmtree)dirpathsr6rz0Buffer._editor_complex_tempfile..cleanups M' " " " " "r5r)r%r~rrHrpathrisabsmkdtemprmakedirsopenrrV)rFheadtailheadtailrfhrrs @r6_editor_complex_tempfilezBuffer._editor_complex_tempfilesk$-(( 2//11 1x==W]]8,, d 7==   8D"$$  2gll7D11G G7<<.. (C' 2 2 2 b HHTY                   # # # # # #  sD((D,/D,validate_and_handleasyncio.Task[None]crtjr\n\dfd }t |S)ze Open code in editor. This returns a future, and runs in a thread executor. rBrCcK tfddd{V}|rtd5}|d}|dr |dd}t |t |_dddn #1swxYwYrdS#wxYw) Nc.SrE)_open_file_in_editor)rrFsr6z4Buffer.open_in_editor..run..6sD55h??r5T) in_executorrbrrrjr6) rrreaddecodeendswithrrMrr)successrrV cleanup_funcrrFrs r6runz"Buffer.open_in_editor..run/sa  !0?????T!!!  3h--W vvxxw77 ==..-#'9D(0dCPTII(V(V(V WWWWWWWWWWWWWWW+300222  s/-CA*B( C(B,,C/B,0C C!r)rr(r~rrrr)rFrrrrs`` @@r6open_in_editorzBuffer.open_in_editor s >>   '$&& & = D%)%B%B%D%D "Hll%)%A%A%C%C "Hl         <yy//666r5rc(tjd}tjd}||dddddg}|D]G}|rC tjt j||gz}|dkcS#t$rYCwxYwHd S) zc Call editor executable. Return True when we received a zero return code. VISUALEDITORz/usr/bin/editorz /usr/bin/nanoz /usr/bin/picoz /usr/bin/viz/usr/bin/emacsrF)renvironget subprocesscallshlexrOSError)rFrvisualeditoreditorsr returncodes r6rzBuffer._open_file_in_editorOs))))           A ",Q8*1L!M!MJ%?***D us/B B B select_first select_lastinsert_common_partcomplete_eventCompleteEvent | Nonec ||z|zdksJt|||||ptddS)z Start asynchronous autocompletion of this buffer. (This will do nothing if a previous completion was still in progress.) r T)completion_requested)rr r r N)rrrr)rFrr r r s r6start_completionzBuffer.start_completionss}k),>>!CCCC ((  ! !)'#5- < d;;; "       r5(Callable[..., Coroutine[Any, Any, None]]cDddt ddfd }|S)z Create function for asynchronous autocompletion. (This consumes the asynchronous completer generator, which possibly runs the completion algorithm in another thread.) rrr^rrBrcd|j}|t||jzd}||jkS)z Return `True` if applying this completion doesn't have any effect. (When it doesn't insert any new text. N)rXrMrZrV)rr^rX replaced_texts r6completion_does_nothingzCBuffer._create_completer_coroutine..completion_does_nothings@ "*!< .&''**CCEEM!JO3 3r5FNrr r r r rCcv Kj}|ptd}jsjsdSt j _d fd }t j d fd }t j|} tj ||4d{V }|23d{V} j |  |sn!t j jkrna6 dddd{Vn#1d{VswxYwY|jn2#|jwxYw j } t| d kr|| d r| dd=|rjr jjdS| s"d_jdS|rd dS|r't| d z dS|rt)||  r\ t| d kr+ fd | D| dd<| dSd_dSt| d krd dSdSdSjj|jkrdSjj|jrt2dS)NT) text_inserted)r=rBrcjkS)ziKeep retrieving completions. Input text has not yet changed while generating completions.)r)rrFsr6proceedzLBuffer._create_completer_coroutine..async_completer..proceeds*n<.async_completer..refresh_while_loadings~0/44666"((***!-,,,,,,,,,(--///////// 0r5r rcTg|]$}|t%Sr4)new_completion_from_positionrM)r3r] common_parts r6r5zOBuffer._create_completer_coroutine..async_completer.. s?...$%!" > >s;?O?O P P...r5rOrBrr)rrrrtr*rr$ ensure_futurerget_completions_asyncr>rrPrMrrrrr@rErr`rLrXrT_Retry)rr r r rrr refresh_taskasync_generatorr^r>r!rrrrFs @@@r6async_completerz;Buffer._create_completer_coroutine..async_completers}H+P}4/P/P/PN" $. -t}MMMN"0D  = = = = = = = %]__N 0 0 0 0 0 0 0#01F1F1H1HIIL 3#N88>RR""""""""$,; " " " " " " "j&299*EEE&**,,, 'wyy"!E  :;;#=>>"E>-?????'5">/!!L!!s= .E09D1<DAD1E01 D;;E0>D;?E00/F)rrr^rrBrFFFN rrr rr rr r rBrC_only_one_at_a_time)rFr(rs` @r6rz"Buffer._create_completer_coroutinesj 4 4 4 4 !& %',37 J !J !J !J !J !J !J !  J !Xr5'Callable[[], Coroutine[Any, Any, None]]c.tdfd }|S)zl Create function for asynchronous auto suggestion. (This can be in another thread.) rBrCcKj}jsjsdSj|d{V}j|kr"|_jdSt rE)rrrvget_suggestion_asyncrrr%)rrrFs r6async_suggestorz>Buffer._create_auto_suggest_coroutine..async_suggestor3s}H d&7 #0EEdHUUUUUUUUJ}((",&++----- r5rr+)rFr1s` r6rz%Buffer._create_auto_suggest_coroutine-s6         $r5c.tdfd }|S)zv Create a function for asynchronous validation while typing. (This can be in another thread.) rBrCc@Kd{VdSrE)rrNsr6async_validatorz?Buffer._create_auto_validate_coroutine..async_validatorPs1&&(( ( ( ( ( ( ( ( ( (r5rr+)rFr4s` r6rz&Buffer._create_auto_validate_coroutineHs6  ) ) ) ) )   )r5c|d}|rK|jr||}nd}||s|dSdSdS)z? Validate buffer and handle the accept action. T)rFN)rrrr)rFvalid keep_texts r6rzBuffer.validate_and_handleVs  ..  " " //55 !  " " $ $ $      r5)NNNNrkrkrkFFFNNFTrsNNNNN)*rtrurvrwrxryrzr{r|r}r~r}rrHrrrrrrrrrrrrrrrrmrrrrrrrrrrrBrCre)NF)rrrrrBrCr)rrHrBr)rrmrBr)rrHrBrC)rBrm)rrmrBrC)rBr)rrrBrC)F)rrrrrBrCr")T)rrrBrC)rrrrrBrH)rrrBrC)rrmrrmrrrBrCr )rrmrBrC)r F)rrmrrrBrC)rrmrBrHr2)r+rHrBrC)rPrmrBrC)rrmrBrrBrC)r>rJrBr*rf)r^rrBrC)rXrmrBr)rnrArkrrBrCrE)rnrArBrC)r{r#rBrC)r~rrBr)rBr)rrrr!rrmrBrC)rrrBrC)FTT) rrHrrrrrrrBrC)rrrBr)Fr )rr rrrrmrBr)rr rBr)Tr )rr rrrrmrBrm)rr rrrrmrBrC)rBr)rrrBr)rrHrBrr)r*)rBr)rBr-)Pr0r1r2r3rGrOrrrrrgrVsetterrWrrrrrrrrrrr rrrrr$r'r)r/r;r?rAr!rrIrLr[rErarcrer#rrxrzr# CHARACTERSr}rrr!rrrrrr`rrrrrrrrrrrrrrrrrrrr4r5r6r)r)s99z'++/"&&*35,..3.3.3$(59"'"&).5948@D<@7;+O&O&O&O&O&bNNNNKP?!?!?!?!?!B3I3I3I3In(;;;;777X7 [,,,[,2&&&X&,,,,"$$$X$!!!!FFFF(////$   X _!!!_!!,!,!,!,!,F)))X)"""""     @         *TTTTTUUUUU0000000000NSSSSSS&NSSSSSS$,           0 G G G G2222)))))0;@))))),'''' # # # #"!"!"!"!H$$$$" * * * * , , , ,    MMMMM022222*1(1(1(1(1(f44444/<.FTTTTT&....!* 77777*##### " " " " " ! ! ! ! !   2J2J2J2J2Jh @@@@>(#(#(#(#T 6 6 6 6*/ V9V9V9V9V9p8*. #####0*. 33333&$$$$!!!! !!!!:-7-7-7-7-7^""""L#!#(/3      0````D6    r5_T.)bound coroutinerBcldtdfd }tt|S)a Decorator that only starts the coroutine only if the previous call has finished. (Used to make sure that we have only one autocompleter, auto suggestor and validator running at a time.) When the coroutine raises `_Retry`, it is restarted. FrrkwrBcnKrdSd |i|d{V ddS#t$rY!wxYw#dwxYw)NTF)r%)rr?r=runnings r6 new_coroutinez*_only_one_at_a_time..new_coroutinevs   F   #)Q-"--------- GGG H GOOOOs0 -0-04)rrr?rrBr)rr r;)r=rBrAs` @r6r,r,lsSG 9( M " ""r5ceZdZdZdS)r%zRetry in `_only_one_at_a_time`.Nr/r4r5r6r%r%s%%%%r5r%bufferfrom_rowrmto_rowrrCc@|jj}|jj}t||}d|z||fd}t |t ||d|_|xj|tzz c_dS)z3 Indent text of a :class:`.Buffer` object.  c|zSrEr4)r4indent_contents r6rzindent..s NQ.transforms? ??6 " " !F & &;;== r5rN)rVrHrBrHrK) rDrErFrrMrNrOrSr_rJs @r6r,r,s/5K/5Kx((Je^N!!!!!!%%j)<rvs8 #""""" DDDDDDDDDDDDDDDD((((((88888811111111 $$$$$$,,,,,,,,--------00000000?????????? 22222222     8 $ $55555555d????????D2:677 ^ ^ ^ ^ ^ ^ ^ ^ xj$./z4/0KKKKKKKK\6 WT#yc4'@"@ABBB####D&&&&&Y&&&@@@@@&@@@@@6- - - - - - r5