o
    �õ±j®D  ã                   @  sü   d Z ddlmZ ddlZddlmZmZ ddlmZ ddl	m
Z
 ddlmZmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZmZ er\ddlmZ ddlmZ g d¢ZG dd„ dƒZ 	 e ddd�Z!G dd„ dƒZ"G dd„ dƒZ#dS )a%  
An :class:`~.KeyProcessor` receives callbacks for the keystrokes parsed from
the input in the :class:`~prompt_toolkit.inputstream.InputStream` instance.

The `KeyProcessor` will according to the implemented keybindings call the
correct callbacks when new key presses are feed through `feed`.
é    )ÚannotationsN)ÚTaskÚsleep)Údeque)Ú	Generator)ÚTYPE_CHECKINGÚAny)Úget_app)ÚEditingMode)Úvi_navigation_mode)ÚKeys)ÚEventé   )ÚBindingÚKeyBindingsBase)ÚApplication)ÚBuffer)ÚKeyProcessorÚKeyPressÚKeyPressEventc                   @  s0   e Zd ZdZddd	d
„Zddd„Zddd„ZdS )r   z‹
    :param key: A `Keys` instance or text (one character).
    :param data: The received string on stdin. (Often vt100 escape codes.)
    NÚkeyú
Keys | strÚdataú
str | NoneÚreturnÚNonec                 C  sH   t |tƒst|ƒdksJ ‚|d u rt |tƒr|j}n|}|| _|| _d S )Nr   )Ú
isinstancer   ÚlenÚvaluer   r   )Úselfr   r   © r    ú›/root/aizidognhua/tmp/workspace/projects/ec89d86c-575f-41c9-af57-ac45cbdbf775/venv/lib/python3.10/site-packages/prompt_toolkit/key_binding/key_processor.pyÚ__init__+   s   

zKeyPress.__init__Ústrc                 C  s   | j j› d| j›d| j›d�S )Nz(key=z, data=ú))Ú	__class__Ú__name__r   r   ©r   r    r    r!   Ú__repr__7   ó   zKeyPress.__repr__ÚotherÚobjectÚboolc                 C  s&   t |tƒsdS | j|jko| j|jkS )NF)r   r   r   r   )r   r*   r    r    r!   Ú__eq__:   s   
zKeyPress.__eq__©N)r   r   r   r   r   r   ©r   r#   )r*   r+   r   r,   )r&   Ú
__module__Ú__qualname__Ú__doc__r"   r(   r-   r    r    r    r!   r   %   s
    
r   ú?Ú_Flush)r   c                   @  s    e Zd ZdZd1dd„Zd2dd	„Zd3dd„Zd4dd„Zd5dd„Zd6d7dd„Z	d6d8dd„Z
d2dd„Zd9dd „Zd:d$d%„Zd;d(d)„Zd;d*d+„Zd2d,d-„Zd2d.d/„Zd0S )<r   aP  
    Statemachine that receives :class:`KeyPress` instances and according to the
    key bindings in the given :class:`KeyBindings`, calls the matching handlers.

    ::

        p = KeyProcessor(key_bindings)

        # Send keys into the processor.
        p.feed(KeyPress(Keys.ControlX, ''))
        p.feed(KeyPress(Keys.ControlC, '')

        # Process all the keys in the queue.
        p.process_keys()

        # Now the ControlX-ControlC callback will be called if this sequence is
        # registered in the key bindings.

    :param key_bindings: `KeyBindingsBase` instance.
    Úkey_bindingsr   r   r   c                 C  s,   || _ t| ƒ| _t| ƒ| _d | _|  ¡  d S r.   )Ú	_bindingsr   Úbefore_key_pressÚafter_key_pressÚ_flush_wait_taskÚreset)r   r5   r    r    r!   r"   ]   s
   

zKeyProcessor.__init__c                 C  s:   g | _ d | _tƒ | _g | _d | _|  ¡ | _| j d ¡ d S r.   )	Ú_previous_key_sequenceÚ_previous_handlerr   Úinput_queueÚ
key_bufferÚargÚ_processÚ_process_coroutineÚsendr'   r    r    r!   r:   g   s   
zKeyProcessor.resetÚkey_pressesúlist[KeyPress]úlist[Binding]c                 C  s(   t dd„ |D ƒƒ}dd„ | j |¡D ƒS )zw
        For a list of :class:`KeyPress` instances. Give the matching handlers
        that would handle this.
        c                 s  ó   � | ]}|j V  qd S r.   ©r   ©Ú.0Úkr    r    r!   Ú	<genexpr>   ó   € z,KeyProcessor._get_matches.<locals>.<genexpr>c                 S  ó   g | ]}|  ¡ r|‘qS r    ©Úfilter©rI   Úbr    r    r!   Ú
<listcomp>‚   ó    z-KeyProcessor._get_matches.<locals>.<listcomp>)Útupler6   Úget_bindings_for_keys)r   rC   Úkeysr    r    r!   Ú_get_matchesz   s   zKeyProcessor._get_matchesr,   c                 C  s:   t dd„ |D ƒƒ}dd„ | j |¡D ƒ}tdd„ |D ƒƒS )z�
        For a list of :class:`KeyPress` instances. Return True if there is any
        handler that is bound to a suffix of this keys.
        c                 s  rF   r.   rG   rH   r    r    r!   rK   ‰   rL   z:KeyProcessor._is_prefix_of_longer_match.<locals>.<genexpr>c                 S  s   h | ]}|j ’qS r    rN   rP   r    r    r!   Ú	<setcomp>�   s    ÿz:KeyProcessor._is_prefix_of_longer_match.<locals>.<setcomp>c                 s  s   � | ]}|ƒ V  qd S r.   r    )rI   Úfr    r    r!   rK   ”   rL   )rT   r6   Úget_bindings_starting_with_keysÚany)r   rC   rV   Úfiltersr    r    r!   Ú_is_prefix_of_longer_match„   s
   
ÿz'KeyProcessor._is_prefix_of_longer_matchúGenerator[None, KeyPress, None]c           
      c  s  � | j }d}	 d}|rd}ndV }|tu rd}n| |¡ |r�|  |¡}|r)d}n|  |¡}dd„ |D ƒ}|r;|}d}|sR|rR| j|d |dd… d� |dd…= n;|s�|s�d}d}tt|ƒddƒD ]#}	|  |d|	… ¡}|r…| j|d |d|	… d� |d|	…= d} nqb|s�|dd	…= q)
zš
        Coroutine implementing the key match algorithm. Key strokes are sent
        into this generator, and it calls the appropriate handlers.
        FTNc                 S  rM   r    )Úeager)rI   Úmr    r    r!   rR   µ   rS   z)KeyProcessor._process.<locals>.<listcomp>éÿÿÿÿ)Úkey_sequencer   r   )r>   r4   ÚappendrW   r]   Ú_call_handlerÚranger   )
r   ÚbufferÚretryÚflushr   ÚmatchesÚis_prefix_of_longer_matchÚeager_matchesÚfoundÚir    r    r!   r@   –   sJ   €



ü
ÏzKeyProcessor._processFÚ	key_pressr   Úfirstc                 C  s$   |r
| j  |¡ dS | j  |¡ dS )zÍ
        Add a new :class:`KeyPress` to the input queue.
        (Don't forget to call `process_keys` in order to process the queue.)

        :param first: If true, insert before everything else.
        N)r=   Ú
appendleftrc   )r   rn   ro   r    r    r!   ÚfeedÑ   s   zKeyProcessor.feedc                 C  s(   |r| j  t|ƒ¡ dS | j  |¡ dS )zG
        :param first: If true, insert before everything else.
        N)r=   Ú
extendleftÚreversedÚextend)r   rC   ro   r    r    r!   Úfeed_multipleÝ   s   zKeyProcessor.feed_multiplec                   sº   t ƒ ‰ d
‡ ‡fdd„}d‡ ‡fdd„}d}|ƒ rS|ƒ }|tu }|jtjk}|s.|s.ˆj ¡  zˆj |¡ W n t	yF   ˆ 
¡  ˆ ¡  ‚ w |sP|sPˆj ¡  |ƒ s|s[ˆ ¡  d	S d	S )a,  
        Process all the keys in the `input_queue`.
        (To be called after `feed`.)

        Note: because of the `feed`/`process_keys` separation, it is
              possible to call `feed` from inside a key binding.
              This function keeps looping until the queue is empty.
        r   r,   c                     s$   ˆ j rtdd„ ˆjD ƒƒS tˆjƒS )Nc                 s  s    � | ]}|j tjkr|V  qd S r.   ©r   r   ÚCPRResponserH   r    r    r!   rK   ø   s   € z?KeyProcessor.process_keys.<locals>.not_empty.<locals>.<genexpr>)Úis_doner[   r=   r,   r    ©Úappr   r    r!   Ú	not_emptyñ   s   
z,KeyProcessor.process_keys.<locals>.not_emptyr   c                    s4   ˆ j rdd„ ˆjD ƒd } ˆj | ¡ | S ˆj ¡ S )Nc                 S  s   g | ]
}|j tjkr|‘qS r    rv   rH   r    r    r!   rR   ÿ   ó    z?KeyProcessor.process_keys.<locals>.get_next.<locals>.<listcomp>r   )rx   r=   ÚremoveÚpopleft)Úcprry   r    r!   Úget_nextü   s
   
z+KeyProcessor.process_keys.<locals>.get_nextFN©r   r,   )r   r   )r	   r4   r   r   rw   r7   ÚfirerA   rB   Ú	Exceptionr:   Úempty_queuer8   Ú_start_timeout)r   r{   r€   Úis_flushrn   Úis_cprr    ry   r!   Úprocess_keysæ   s.   		
û
ìÿzKeyProcessor.process_keysc                 C  s&   t | jƒ}| j ¡  dd„ |D ƒ}|S )zF
        Empty the input queue. Return the unprocessed input.
        c                 S  s   g | ]
}|j tjkr|‘qS r    rv   rH   r    r    r!   rR   )  r|   z,KeyProcessor.empty_queue.<locals>.<listcomp>)Úlistr=   Úclear)r   rC   r    r    r!   r„   !  s   

zKeyProcessor.empty_queueÚhandlerr   rb   c                 C  s&  t ƒ }|jj}t|jjƒ}|jj}| j}d | _tt	 
| ¡||| j|| jkd�}| |¡r2|jj ¡  ddlm}	 z| |¡ |  |¡ W n |	yR   |j ¡  Y nw |rZ|  |¡ || _|| _| ¡ r‹|jjrw|rw|jj}
|
d urw|
 |¡ |jjr�|r�|D ]}|j j|j7  _qd S d S d S d S )N)r?   rb   Úprevious_key_sequenceÚ	is_repeatr   )ÚEditReadOnlyBuffer)r	   Úemacs_stateÚis_recordingr,   Úvi_stateÚrecording_registerÚtemporary_navigation_moder?   r   ÚweakrefÚrefr;   r<   Úsave_beforerz   Úcurrent_bufferÚsave_to_undo_stackÚprompt_toolkit.bufferrŽ   ÚcallÚ_fix_vi_cursor_positionÚoutputÚbellÚ_leave_vi_temp_navigation_modeÚrecord_in_macroÚcurrent_recordingrt   r   )r   r‹   rb   rz   Úwas_recording_emacsÚwas_recording_viÚwas_temporary_navigation_moder?   ÚeventrŽ   Ú	recordingrJ   r    r    r!   rd   ,  sJ   û
	
ý

÷zKeyProcessor._call_handlerr¤   r   c                 C  sT   |j }|j}|j}tƒ r$|jjr&t|jjƒdkr(| jd8  _||_dS dS dS dS )z¿
        After every command, make sure that if we are in Vi navigation mode, we
        never put the cursor after the last character of a line. (Unless it's
        an empty line.)
        r   r   N)	rz   r—   Úpreferred_columnr   ÚdocumentÚis_cursor_at_the_end_of_liner   Úcurrent_lineÚcursor_position)r   r¤   rz   Úbuffr¦   r    r    r!   r›   _  s   ÿþ
÷z$KeyProcessor._fix_vi_cursor_positionc                 C  s@   |j }|jtjkr|jjdu r| jdu rd|j_dS dS dS dS )z†
        If we're in Vi temporary navigation (normal) mode, return to
        insert/replace mode after executing one action.
        NF)rz   Úediting_moder
   ÚVIr‘   Úoperator_funcr?   r“   )r   r¤   rz   r    r    r!   rž   t  s   ýz+KeyProcessor._leave_vi_temp_navigation_modec                   sZ   t ƒ }|j‰ˆdu rdS d‡ ‡‡fdd„}d‡fdd„‰ ˆjr$ˆj ¡  | |ƒ ¡ˆ_dS )	a%  
        Start auto flush timeout. Similar to Vim's `timeoutlen` option.

        Start a background coroutine with a timer. When this timeout expires
        and no key was pressed in the meantime, we flush all data in the queue
        and call the appropriate key binding handlers.
        Nr   r   c                   “  s,   �t ˆƒI dH  tˆjƒdkrˆ ƒ  dS dS )zWait for timeout.Nr   )r   r   r>   r    ©Ú
flush_keysr   Útimeoutr    r!   ÚwaitŽ  s
   €
þz)KeyProcessor._start_timeout.<locals>.waitc                     s   ˆ   t¡ ˆ  ¡  dS )zFlush keys.N)rq   r4   rˆ   r    r'   r    r!   r°   —  s   
z/KeyProcessor._start_timeout.<locals>.flush_keys©r   r   )r	   Ú
timeoutlenr9   ÚcancelÚcreate_background_task)r   rz   r²   r    r¯   r!   r…   €  s   	
zKeyProcessor._start_timeoutc                 C  s"   | j ttjd�dd� |  ¡  dS )zG
        Send SIGINT. Immediately call the SIGINT key handler.
        rG   T)ro   N)rq   r   r   ÚSIGINTrˆ   r'   r    r    r!   Úsend_sigint¡  s   zKeyProcessor.send_sigintN)r5   r   r   r   r³   )rC   rD   r   rE   )rC   rD   r   r,   )r   r^   )F)rn   r   ro   r,   r   r   )rC   rD   ro   r,   r   r   )r   rD   )r‹   r   rb   rD   r   r   )r¤   r   r   r   )r&   r0   r1   r2   r"   r:   rW   r]   r@   rq   ru   rˆ   r„   rd   r›   rž   r…   r¸   r    r    r    r!   r   G   s     






;
	
;

3

!r   c                   @  s�   e Zd ZdZd(dd„Zd)dd„Zed)dd„ƒZed*dd„ƒZed+dd„ƒZ	ed,dd„ƒZ
ed-dd„ƒZed.d d!„ƒZd/d#d$„Zed+d%d&„ƒZd'S )0r   at  
    Key press event, delivered to key bindings.

    :param key_processor_ref: Weak reference to the `KeyProcessor`.
    :param arg: Repetition argument.
    :param key_sequence: List of `KeyPress` instances.
    :param previouskey_sequence: Previous list of `KeyPress` instances.
    :param is_repeat: True when the previous event was delivered to the same handler.
    Úkey_processor_refú#weakref.ReferenceType[KeyProcessor]r?   r   rb   rD   rŒ   r�   r,   r   r   c                 C  s*   || _ || _|| _|| _|| _tƒ | _d S r.   )Ú_key_processor_refrb   rŒ   r�   Ú_argr	   Ú_app)r   r¹   r?   rb   rŒ   r�   r    r    r!   r"   ´  s   zKeyPressEvent.__init__r#   c                 C  s   d| j ›d| j›d| j›d�S )NzKeyPressEvent(arg=z, key_sequence=z, is_repeat=r$   )r?   rb   r�   r'   r    r    r!   r(   Æ  r)   zKeyPressEvent.__repr__c                 C  s   | j d jS )Nra   )rb   r   r'   r    r    r!   r   É  s   zKeyPressEvent.datar   c                 C  s   |   ¡ }|d u rtdƒ‚|S )Nz.KeyProcessor was lost. This should not happen.)r»   rƒ   )r   Ú	processorr    r    r!   Úkey_processorÍ  s   zKeyPressEvent.key_processorúApplication[Any]c                 C  ó   | j S )z3
        The current `Application` object.
        )r½   r'   r    r    r!   rz   Ô  s   zKeyPressEvent.appr   c                 C  s   | j jS )z%
        The current buffer.
        )rz   r—   r'   r    r    r!   r—   Û  s   zKeyPressEvent.current_bufferÚintc                 C  s0   | j dkrdS t| j pdƒ}t|ƒdkrd}|S )z&
        Repetition argument.
        ú-ra   r   i@B )r¼   rÂ   )r   Úresultr    r    r!   r?   â  s   
zKeyPressEvent.argc                 C  s
   | j duS )zF
        True if repetition argument was explicitly provided.
        N)r¼   r'   r    r    r!   Úarg_presentò  s   
zKeyPressEvent.arg_presentr   c                 C  sZ   |dv sJ ‚| j }|dkr|du s|dksJ ‚|}n|du r!|}n|› |› �}|| j_dS )zb
        Add digit to the input argument.

        :param data: the typed digit as string
        z-0123456789rÃ   N)r¼   r¿   r?   )r   r   ÚcurrentrÄ   r    r    r!   Úappend_to_arg_countù  s   z!KeyPressEvent.append_to_arg_countc                 C  rÁ   )zFor backward-compatibility.)rz   r'   r    r    r!   Úcli  s   zKeyPressEvent.cliN)r¹   rº   r?   r   rb   rD   rŒ   rD   r�   r,   r   r   r/   )r   r   )r   rÀ   )r   r   )r   rÂ   r�   )r   r#   r   r   )r&   r0   r1   r2   r"   r(   Úpropertyr   r¿   rz   r—   r?   rÅ   rÇ   rÈ   r    r    r    r!   r   ©  s&    



r   )$r2   Ú
__future__r   r”   Úasyncior   r   Úcollectionsr   Úcollections.abcr   Útypingr   r   Ú"prompt_toolkit.application.currentr	   Úprompt_toolkit.enumsr
   Úprompt_toolkit.filters.appr   Úprompt_toolkit.keysr   Úprompt_toolkit.utilsr   r5   r   r   Úprompt_toolkit.applicationr   r™   r   Ú__all__r   r4   r   r   r    r    r    r!   Ú<module>   s0      d