U
    bh1x                     @  s  d dl mZ d dlZd dlZd dlmZ d dlmZ d dlm	Z	 ddl
mZ ejdksZtesrd dlZd d	lmZ d d
lmZmZmZ d dlmZmZ d dlmZmZmZmZ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'm(Z( d dl)m*Z*m+Z+m,Z,m-Z-m.Z. ddl/m0Z0 ddl1m2Z2 ddl3m4Z4 ddddddgZ5dZ6dZ7dZ8dZ9dZ:G dd  d e2Z;G d!d de;Z<G d"d dZ=G d#d$ d$Z>G d%d& d&Z?e	d d'd(d)d*dZ@e	d d(d+d,dZAG d-d dZBG d.d deBZCd/d0d1d2ZDdS )3    )annotationsN)abstractmethod)get_running_loop)contextmanager   )SPHINX_AUTODOC_RUNNINGwin32)windll)Arraybyrefpointer)DWORDHANDLE)CallableContextManagerIterableIteratorTextIOrun_in_executor_with_context)create_win32_eventwait_for_handles)KeyPress)Keys)MouseButtonMouseEventType)INPUT_RECORDKEY_EVENT_RECORDMOUSE_EVENT_RECORDSTD_INPUT_HANDLE
EventTypes   )REVERSE_ANSI_SEQUENCES)Input)Vt100Parser
Win32InputConsoleInputReaderraw_modecooked_modeattach_win32_inputdetach_win32_input   i   c                   @  s4   e Zd ZdZddddZeeddddZd	S )
_Win32InputBasez;
    Base class for `Win32Input` and `Win32PipeInput`.
    Nonereturnc                 C  s   t  | _d S N)_Win32Handleswin32_handlesself r5   >/tmp/pip-unpacked-wheel-9s95tbmv/prompt_toolkit/input/win32.py__init__A   s    z_Win32InputBase.__init__r   c                 C  s   d S r0   r5   r3   r5   r5   r6   handleD   s    z_Win32InputBase.handleN)__name__
__module____qualname____doc__r7   propertyr   r8   r5   r5   r5   r6   r,   <   s
   r,   c                      s   e Zd ZdZd'ddd fddZdd	d
ddZd	dddZddddZddddZe	ddddZ
d	dddZd	dddZddddZddd d!Zddd"d#Ze	d$dd%d&Z  ZS )(r%   z<
    `Input` class that reads from the Windows console.
    NzTextIO | Noner-   )stdinr/   c                   s2   t    t | _|  | jr&t | _nt | _d S r0   )superr7   _is_win_vt100_input_enabled_use_virtual_terminal_inputVt100ConsoleInputReaderconsole_input_readerr&   )r4   r>   	__class__r5   r6   r7   O   s    

zWin32Input.__init__Callable[[], None]zContextManager[None])input_ready_callbackr/   c                 C  s
   t | |S )zj
        Return a context manager that makes this input active in the current
        event loop.
        )r)   )r4   rG   r5   r5   r6   attachZ   s    zWin32Input.attachr.   c                 C  s   t | S )z{
        Return a context manager that makes sure that this input is not active
        in the current event loop.
        )r*   r3   r5   r5   r6   detacha   s    zWin32Input.detachlist[KeyPress]c                 C  s   t | j S r0   )listrC   readr3   r5   r5   r6   	read_keysh   s    zWin32Input.read_keysc                 C  s   d S r0   r5   r3   r5   r5   r6   flushk   s    zWin32Input.flushboolc                 C  s   dS )NFr5   r3   r5   r5   r6   closedn   s    zWin32Input.closedc                 C  s   t | jdS )N) use_win10_virtual_terminal_input)r'   rA   r3   r5   r5   r6   r'   r   s    zWin32Input.raw_modec                 C  s   t  S r0   )r(   r3   r5   r5   r6   r(   w   s    zWin32Input.cooked_modeintc                 C  s
   t j S r0   )sysr>   filenor3   r5   r5   r6   rT   z   s    zWin32Input.filenostrc                 C  s   dS )Nzwin32-inputr5   r3   r5   r5   r6   typeahead_hash   s    zWin32Input.typeahead_hashc                 C  s   | j   d S r0   )rC   closer3   r5   r5   r6   rW      s    zWin32Input.closer   c                 C  s   | j jS r0   )rC   r8   r3   r5   r5   r6   r8      s    zWin32Input.handle)N)r9   r:   r;   r<   r7   rH   rI   rM   rN   r=   rP   r'   r(   rT   rV   rW   r8   __classcell__r5   r5   rD   r6   r%   J   s   c                "   @  s  e Zd ZdZejejejejej	ej
ejejejejejejejejejejejejejejejejejejejejejej ej!ej"ej#ej$ej%d!Z&ej'ej(ej)ej*ej+ej,ej-ej.ej/ej0ej1ej2ej3ej4ej5ej6ej7ej8ej9ej:ej;ej<dZ=dZ>dZ?dZ@dZAdZBd.d
ddddZCddddZDddddZEdddddZFddddddZGeHddd d!d"ZIeHdd
d#d$d%ZJd&dd'd(d)ZKd*dd'd+d,ZLd-S )/r&   z|
    :param recognize_paste: When True, try to discover paste actions and turn
        the event into a BracketedPaste.
    )!                                  	   
                                                               )!   "   #   $   %   &   '   (   -   .   p   q   r   s   t   u   v   w   x   y   z   {   r   r!         r+   TrO   r-   )recognize_paster/   c                 C  sZ   d | _ || _|  tj r.ttjt	| _
n(tdtjtjB | _ tt| j | _
d S )NCONIN$)_fdconr   rS   r>   isattyr   r	   kernel32GetStdHandler   r8   osopenO_RDWRO_BINARYmsvcrtget_osfhandle)r4   r   r5   r5   r6   r7      s    
zConsoleInputReader.__init__r.   c                 C  s   | j dk	rt| j  dS zClose fdcon.Nr   r   rW   r3   r5   r5   r6   rW      s    
zConsoleInputReader.closeIterable[KeyPress]c           	   	   #  s2  d}t d}t| }| }t jgdds.dS tj jt||t| t 	||} fdd|D }t 
|} jr$ |r$t|}|D ]}g }|rt|jtr|jtjtjhkr||j zt|}W q tk
r   d}Y qX q|rttjd|V  |dk	r|V  qn
|E dH  dS )
        Return a list of `KeyPress` instances. It won't return anything when
        there was nothing to read.  (This function doesn't block.)

        http://msdn.microsoft.com/en-us/library/windows/desktop/ms684961(v=vs.85).aspx
           r   timeoutNc                   s   g | ]}  |qS r5   )_insert_key_data).0keyr3   r5   r6   
<listcomp>  s     z+ConsoleInputReader.read.<locals>.<listcomp> )r   r   r   r8   r	   r   ReadConsoleInputWr   rK   	_get_keys_merge_paired_surrogatesr   	_is_pasteiter
isinstancer   r   ControlJControlMappenddatanextStopIterationr   ZBracketedPastejoin)	r4   	max_countrL   arrtypeinput_recordsZall_keysgenkr   r5   r3   r6   rL      sD       

zConsoleInputReader.readr   )	key_pressr/   c                 C  s6   |j r
|S t|jtr&t|jd}nd}t|j|S )z@
        Insert KeyPress data, for vt100 compatibility.
        r   )r   r   r   r   r"   getr   )r4   r   r   r5   r5   r6   r   *  s    z#ConsoleInputReader._insert_key_datar   Array[INPUT_RECORD]zIterator[KeyPress]rL   r   r/   c                 c  st   t |jD ]d}|| }|jtkr
t|jt|j }t|trT|jrT| 	|E dH  q
t|t
r
| |E dH  q
dS )R
        Generator that yields `KeyPress` objects from the input records.
        N)rangevalue	EventTyper    getattrEventr   r   KeyDown_event_to_key_pressesr   _handle_mouse)r4   rL   r   iirevr5   r5   r6   r   8  s    

zConsoleInputReader._get_keysrJ   )key_pressesr/   c                 c  s   d}| D ]}t |jt }|o6d|j  ko2dkn  }|oTd|j  koPdkn  }|r|r|j|j ddd}t||}n|V  d}|r|}q|V  q|r|V  dS )zm
        Combines consecutive KeyPresses with high and low surrogates into
        single characters
        Nu   u   u   u   z	utf-16-lesurrogatepass)r   r   r   encodedecoder   )r   Zbuffered_high_surrogater   Zis_textZis_high_surrogateZis_low_surrogateZfullcharr5   r5   r6   r   P  s,     z+ConsoleInputReader._merge_paired_surrogates)keysr/   c                 C  sJ   d}d}| D ],}t |jts$|d7 }|jtjkr|d7 }q|dkoH|dkS )a<  
        Return `True` when we should consider this list of keys as a paste
        event. Pasted text on windows will be turned into a
        `Keys.BracketedPaste` event. (It's not 100% correct, but it is probably
        the best possible way to detect pasting of text and handle that
        correctly.)
        r   r!   )r   r   r   r   )r   Z
text_countZnewline_countr   r5   r5   r6   r   q  s    
zConsoleInputReader._is_paster   )r   r/   c                 C  s  t |tr|jstd}|j}|jj}|dd}|dkrZ|j| j	krt
| j	|j d}n:|| jkr| j| tjkrxd}t
| j| |}n
t
||}|| j@ s|| j@ r|| j@ r|rtjtjtjtjtjtjtjtjtjtjtjtjtjtjtjtj tj!tj"i	}|#|j$|j$|_$|| j@ s2|| j@ r|rtjtj%tjtj&tjtj'tjtj(tjtj)tjtj*tjtj+tj,tj-tjtj.tj!tj/i
}|#|j$|j$|_$|| j@ r|rtj0tj1tjtj2tjtj3tjtj4tjtj5tjtj6tjtj7tjtj8tj,tj9tjtj:tj!tj;i}|#|j$|j$|_$|| j@ s6|| j@ rT|rT|j<dkrTt
tj=d}|| j@ sl|| j@ r|r|j$tjkrt
tj>d|gS |r|| j?@ }|rt
tj>d|gS |gS ng S dS )zU
        For this `KEY_EVENT_RECORD`, return a list of `KeyPress` instances.
        Nzutf-8r    r   
 )@r   r   r   AssertionErrorZControlKeyStateuCharUnicodeCharr   ZVirtualKeyCodekeycodesr   mappingsr   r   LEFT_CTRL_PRESSEDRIGHT_CTRL_PRESSEDSHIFT_PRESSEDLeftZControlShiftLeftRightZControlShiftRightUpZControlShiftUpDownZControlShiftDownHomeZControlShiftHomeEndZControlShiftEndInsertZControlShiftInsertPageUpZControlShiftPageUpPageDownZControlShiftPageDownr   r   ZControlLeftZControlRightZ	ControlUpZControlDownZControlHomeZ
ControlEndZControlInsertDeleteZControlDeleteZControlPageUpZControlPageDownZTabZBackTabZ	ShiftLeftZ
ShiftRightZShiftUpZ	ShiftDownZ	ShiftHomeZShiftEndZShiftInsertZShiftDeleteZShiftPageUpZShiftPageDownr   ControlSpaceEscapeLEFT_ALT_PRESSED)r4   r   resultZcontrol_key_stateu_charZ
ascii_charmappingZmeta_pressedr5   r5   r6   r     s    

	                              


z(ConsoleInputReader._event_to_key_pressesr   c                 C  s   |j }|j}d}tj}|t@ r6|dkr.tj}qTtj}n|tkrFtj	}n|t
krTtj}|t@ rbtj}|dkr|dkrztj}ntj}d|j|jt|jjt|jjg}ttj|gS )zK
        Handle mouse events. Return a list of KeyPress instances.
        Nr   ;)Z
EventFlagsZButtonStater   NONEMOUSE_WHEELEDr   Z	SCROLL_UPZSCROLL_DOWNFROM_LEFT_1ST_BUTTON_PRESSEDLEFTRIGHTMOST_BUTTON_PRESSEDRIGHTMOUSE_MOVEDZ
MOUSE_MOVEZ
MOUSE_DOWNZMOUSE_UPr   r   rU   ZMousePositionXYr   r   ZWindowsMouseEvent)r4   r   Zevent_flagsZbutton_stateZ
event_typebuttonr   r5   r5   r6   r     s4    

z ConsoleInputReader._handle_mouseN)T)Mr9   r:   r;   r<   r   r   r   ZControlAZControlBZControlCZControlDZControlEZControlFZControlGZControlHZControlIr   ZControlKZControlLr   ZControlNZControlOZControlPZControlQZControlRZControlSZControlTZControlUZControlVZControlWZControlXZControlYZControlZZControlBackslashZControlSquareCloseZControlCircumflexZControlUnderscoreZ	Backspacer   r   r   r   r   r   r   r   r   r   r   ZF1ZF2ZF3ZF4ZF5ZF6ZF7ZF8ZF9ZF10ZF11ZF12r   r   ZRIGHT_ALT_PRESSEDr   r   r   r7   rW   rL   r   r   staticmethodr   r   r   r   r5   r5   r5   r6   r&      s   '>  c                   @  sL   e Zd ZdZddddZddddZddd	d
ZddddddZdS )rB   a  
    Similar to `ConsoleInputReader`, but for usage when
    `ENABLE_VIRTUAL_TERMINAL_INPUT` is enabled. This assumes that Windows sends
    us the right vt100 escape sequences and we parse those with our vt100
    parser.

    (Using this instead of `ConsoleInputReader` results in the "data" attribute
    from the `KeyPress` instances to be more correct in edge cases, because
    this responds to for instance the terminal being in application cursor keys
    mode.)
    r-   r.   c                   sl   d  _ g  _t fdd _  tj r@ttj	
t _n(tdtjtjB  _ tt j  _d S )Nc                   s    j | S r0   )_bufferr   )r   r3   r5   r6   <lambda>M      z2Vt100ConsoleInputReader.__init__.<locals>.<lambda>r   )r   r   r$   _vt100_parserrS   r>   r   r   r	   r   r   r   r8   r   r   r   r   r   r   r3   r5   r3   r6   r7   H  s    

z Vt100ConsoleInputReader.__init__c                 C  s   | j dk	rt| j  dS r   r   r3   r5   r5   r6   rW   Y  s    
zVt100ConsoleInputReader.closer   c                 C  sx   d}t d}t| }| }t| jgdds.g S tj| jt||t| | ||D ]}| j	
| qV| j}g | _|S )r   r   r   r   )r   r   r   r8   r	   r   r   r   r   r   feedr   )r4   r   rL   r   r   Zkey_datar   r5   r5   r6   rL   ^  s"       zVt100ConsoleInputReader.readr   r   zIterator[str]r   c                 c  s^   t |jD ]N}|| }|jtkr
t|jt|j }t|tr
|jr
|j	j
}|dkr
|V  q
dS )r   r   N)r   r   r   r    r   r   r   r   r   r   r   )r4   rL   r   r   r   r   r   r5   r5   r6   r     s    
z!Vt100ConsoleInputReader._get_keysN)r9   r:   r;   r<   r7   rW   rL   r   r5   r5   r5   r6   rB   ;  s
   %rB   c                   @  s@   e Zd ZdZddddZddddd	d
ZdddddZdS )r1   a  
    Utility to keep track of which handles are connectod to which callbacks.

    `add_win32_handle` starts a tiny event loop in another thread which waits
    for the Win32 handle to become ready. When this happens, the callback will
    be called in the current asyncio event loop using `call_soon_threadsafe`.

    `remove_win32_handle` will stop this tiny event loop.

    NOTE: We use this technique, so that we don't have to use the
          `ProactorEventLoop` on Windows and we can wait for things like stdin
          in a `SelectorEventLoop`. This is important, because our inputhook
          mechanism (used by IPython), only works with the `SelectorEventLoop`.
    r-   r.   c                 C  s   i | _ i | _d S r0   )_handle_callbacks_remove_eventsr3   r5   r5   r6   r7     s    z_Win32Handles.__init__r   rF   )r8   callbackr/   c                   s~   j }|dkrtd|  t  | j|< t | j|< dd fddddfddtd	 dS )
z7
        Add a Win32 handle to the event loop.
        NInvalid handle.r-   r.   c                
     s   z
   W 5 t d X d S )Nloopr   r5   )r   r  waitr5   r6   ready  s    
z-_Win32Handles.add_win32_handle.<locals>.readyc                    s2   t  g} | kr$tj d S  d S r0   )r   r	   r   ZCloseHandleZcall_soon_threadsafe)r   )r8   r  r  remove_eventr5   r6   r    s
    z,_Win32Handles.add_win32_handle.<locals>.waitr  )r   
ValueErrorremove_win32_handler   r   r   r   r   )r4   r8   r   Zhandle_valuer5   )r   r8   r  r  r  r  r6   add_win32_handle  s    



z_Win32Handles.add_win32_handlezCallable[[], None] | None)r8   r/   c                 C  sn   |j dkrdS z| j|j }W n tk
r4   Y nX tj| z| j|j W S  tk
rh   Y dS X dS )zt
        Remove a Win32 handle from the event loop.
        Return either the registered handler or `None`.
        N)r   r   popKeyErrorr	   r   ZSetEventr   )r4   r8   eventr5   r5   r6   r    s    
z!_Win32Handles.remove_win32_handleN)r9   r:   r;   r<   r7   r  r  r5   r5   r5   r6   r1     s   +r1   rF   zIterator[None])inputr   r/   c              
   c  s`   | j }| j}|jdkrtd||}||| z
dV  W 5 || |rZ||| X dS )z
    Context manager that makes this input active in the current event loop.

    :param input: :class:`~prompt_toolkit.input.Input` object.
    :param input_ready_callback: Called when the input is ready to read.
    Nr   r2   r8   r   r  r  r  )r  r   r2   r8   previous_callbackr5   r5   r6   r)     s    




)r  r/   c              
   c  sJ   | j }| j}|jd krtd||}z
d V  W 5 |rD||| X d S )Nr   r  )r  r2   r8   r  r5   r5   r6   r*     s    


c                   @  sP   e Zd ZdZddddddd	Zdd
ddZdd
ddZdddddZdS )r'   z
    ::

        with raw_mode(stdin):
            ''' the windows terminal is now in 'raw' mode. '''

    The ``fileno`` attribute is ignored. This is to be compatible with the
    `raw_input` method of `.vt100_input`.
    NFz
int | NonerO   r-   )rT   rQ   r/   c                 C  s   t tjt| _|| _d S r0   )r   r	   r   r   r   r8   rQ   )r4   rT   rQ   r5   r5   r6   r7   ,  s    zraw_mode.__init__r.   c                 C  s,   t  }tj| jt| || _|   d S r0   )r   r	   r   GetConsoleModer8   r   original_mode_patch)r4   r  r5   r5   r6   	__enter__2  s    zraw_mode.__enter__c                 C  sD   d}d}d}| j j||B |B  @ }| jr0|tO }tj| j| d S Nr+   r   r!   )r  r   rQ   ENABLE_VIRTUAL_TERMINAL_INPUTr	   r   SetConsoleModer8   )r4   ENABLE_ECHO_INPUTENABLE_LINE_INPUTENABLE_PROCESSED_INPUTZnew_moder5   r5   r6   r  :  s    
zraw_mode._patchobject)ar/   c                 G  s   t j| j| j d S r0   )r	   r   r  r8   r  )r4   r  r5   r5   r6   __exit__I  s    zraw_mode.__exit__)NF)r9   r:   r;   r<   r7   r  r  r  r5   r5   r5   r6   r'   !  s      c                   @  s   e Zd ZdZddddZdS )r(   zx
    ::

        with cooked_mode(stdin):
            ''' The pseudo-terminal stdin is now used in cooked mode. '''
    r-   r.   c                 C  s0   d}d}d}t j| j| jj||B |B B  d S r  )r	   r   r  r8   r  r   )r4   r  r  r  r5   r5   r6   r  V  s    
zcooked_mode._patchN)r9   r:   r;   r<   r  r5   r5   r5   r6   r(   N  s   rO   r.   c               
   C  s^   t tjt} td}tj| t| ztj| tt	}|dkW S tj| | X dS )z_
    Returns True when we're running Windows and VT100 escape sequences are
    supported.
    r   r!   N)
r   r	   r   r   r   r   r  r   r  r  )Zhconsoler  r   r5   r5   r6   r@   c  s     r@   )E
__future__r   r   rS   abcr   Zasyncior   
contextlibr   utilsr   platformr   r   ctypesr	   r
   r   r   Zctypes.wintypesr   r   typingr   r   r   r   r   Zprompt_toolkit.eventloopr   Zprompt_toolkit.eventloop.win32r   r   Z(prompt_toolkit.key_binding.key_processorr   Zprompt_toolkit.keysr   Zprompt_toolkit.mouse_eventsr   r   Zprompt_toolkit.win32_typesr   r   r   r   r    Zansi_escape_sequencesr"   baser#   Zvt100_parserr$   __all__r   r   r   r   r  r,   r%   r&   rB   r1   r)   r*   r'   r(   r@   r5   r5   r5   r6   <module>   sb   B   2`X-