o
    iD                     @  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mZ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
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)TYPE_CHECKINGAnyDeque	GeneratorListOptionalUnion)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$   c/var/www/edux/Edux_v2/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__5   s   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__8   s   
zKeyPress.__eq__N)r   r   r   r   r   r   r   r'   )r-   r.   r   r/   )r*   
__module____qualname____doc__r&   r,   r0   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 r1   )	_bindingsr   before_key_pressafter_key_press_flush_wait_taskreset)r#   r8   r$   r$   r%   r&   [   s
   

zKeyProcessor.__init__c                 C  s:   g | _ d | _t | _g | _d | _|  | _| jd  d S r1   )	_previous_key_sequence_previous_handlerr   input_queue
key_bufferarg_process_process_coroutinesendr+   r$   r$   r%   r=   e   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 r1   r   .0kr$   r$   r%   	<genexpr>}       z,KeyProcessor._get_matches.<locals>.<genexpr>c                 S     g | ]}|  r|qS r$   filterrL   br$   r$   r%   
<listcomp>       z-KeyProcessor._get_matches.<locals>.<listcomp>)tupler9   get_bindings_for_keys)r#   rF   keysr$   r$   r%   _get_matchesx   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  rI   r1   rJ   rK   r$   r$   r%   rN      rO   z:KeyProcessor._is_prefix_of_longer_match.<locals>.<genexpr>c                 S  s   h | ]}|j qS r$   rQ   rS   r$   r$   r%   	<setcomp>   s    z:KeyProcessor._is_prefix_of_longer_match.<locals>.<setcomp>c                 s  s    | ]}| V  qd S r1   r$   )rL   fr$   r$   r%   rN      rO   )rW   r9   get_bindings_starting_with_keysany)r#   rF   rY   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  rP   r$   )eager)rL   mr$   r$   r%   rU      rV   z)KeyProcessor._process.<locals>.<listcomp>)key_sequencer   r   )rA   r7   appendrZ   r`   _call_handlerranger!   )
r#   bufferretryflushr   matchesis_prefix_of_longer_matcheager_matchesfoundir$   r$   r%   rC      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@   
appendleftrf   )r#   rq   rr   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#   rF   rr   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 r1   r   r   CPRResponserK   r$   r$   r%   rN      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$   ry   rK   r$   r$   r%   rU          z?KeyProcessor.process_keys.<locals>.get_next.<locals>.<listcomp>r   )r{   r@   removepopleft)cprr|   r$   r%   get_next   s
   
z+KeyProcessor.process_keys.<locals>.get_nextFNr   r/   )r   r   )r   r7   r   r   rz   r:   firerD   rE   	Exceptionr=   empty_queuer;   _start_timeout)r#   r~   r   is_flushrq   is_cprr$   r|   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$   ry   rK   r$   r$   r%   rU   '  r   z,KeyProcessor.empty_queue.<locals>.<listcomp>)listr@   clear)r#   rF   r$   r$   r%   r     s   

zKeyProcessor.empty_queuehandlerr   re   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)rB   re   previous_key_sequence	is_repeatr   )EditReadOnlyBuffer)r   emacs_stateis_recordingr/   vi_staterecording_registertemporary_navigation_moderB   r   weakrefrefr>   r?   save_beforer}   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_recordingrw   r   )r#   r   re   r}   was_recording_emacswas_recording_viwas_temporary_navigation_moderB   eventr   	recordingrM   r$   r$   r%   rg   *  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)	r}   r   preferred_columnr   documentis_cursor_at_the_end_of_liner!   current_linecursor_position)r#   r   r}   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)r}   editing_moder   VIr   operator_funcrB   r   )r#   r   r}   r$   r$   r%   r   r  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!   rA   r$   
flush_keysr#   timeoutr$   r%   wait  s
   
z)KeyProcessor._start_timeout.<locals>.waitc                     s     t    dS )zFlush keys.N)rt   r7   r   r$   r+   r$   r%   r     s   
z/KeyProcessor._start_timeout.<locals>.flush_keysr   r   )r   
timeoutlenr<   cancelcreate_background_task)r#   r}   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.
        rJ   T)rr   N)rt   r   r   SIGINTr   r+   r$   r$   r%   send_sigint  s   zKeyProcessor.send_sigintN)r8   r   r   r   r   )rF   rG   r   rH   )rF   rG   r   r/   )r   ra   )F)rq   r   rr   r/   r   r   )rF   rG   rr   r/   r   r   )r   rG   )r   r   re   rG   r   r   )r   r   r   r   )r*   r3   r4   r5   r&   r=   rZ   r`   rC   rt   rx   r   r   rg   r   r   r   r   r$   r$   r$   r%   r   E   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]rB   r   re   rG   r   r   r/   r   r   c                 C  s*   || _ || _|| _|| _|| _t | _d S r1   )_key_processor_refre   r   r   _argr   _app)r#   r   rB   re   r   r   r$   r$   r%   r&     s   zKeyPressEvent.__init__r'   c                 C  s   d | j| j| jS )Nz:KeyPressEvent(arg={!r}, key_sequence={!r}, is_repeat={!r}))formatrB   re   r   r+   r$   r$   r%   r,     s
   zKeyPressEvent.__repr__c                 C  s   | j d jS )Nrd   )re   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%   r}     s   zKeyPressEvent.appr   c                 C  s   | j jS )z%
        The current buffer.
        )r}   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.
        -rd   r   i@B )r   r   )r#   resultr$   r$   r%   rB     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   rB   )r#   r   currentr   r$   r$   r%   append_to_arg_count  s   z!KeyPressEvent.append_to_arg_countc                 C  r   )zFor backward-compatibility.)r}   r+   r$   r$   r%   cli  s   zKeyPressEvent.cliN)r   r   rB   r   re   rG   r   rG   r   r/   r   r   r2   )r   r   )r   r   )r   r   )r   r   r   )r   r'   r   r   )r*   r3   r4   r5   r&   r,   propertyr   r   r}   r   rB   r   r   r   r$   r$   r$   r%   r     s&    



r   )'r5   
__future__r   r   asyncior   r   collectionsr   typingr   r   r   r	   r
   r   r   "prompt_toolkit.application.currentr   prompt_toolkit.enumsr   prompt_toolkit.filters.appr   prompt_toolkit.keysr   prompt_toolkit.utilsr   r8   r   r   prompt_toolkit.applicationr   r   r   __all__r   r7   r   r   r$   r$   r$   r%   <module>   s.    $  d