o
    fD                     @  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
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
rXd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)TYPE_CHECKINGAny	Generator)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    [/var/www/html/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__6      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__9   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:   f   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_matchesy   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|sd}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   s  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   F   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   typingr   r   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>   s.      d