U
    bh:                     @  s   d dl mZ d dlZd dl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mZ ddlmZmZmZ dd	lmZ d
dgZG dd
 d
eZG dd deZG dd deZdS )    )annotationsN)CallableIterable
NamedTupleSequence)Document)FilterOrBool	to_filter)AnyFormattedTextStyleAndTextTuples   )CompleteEvent	Completer
Completion)WordCompleterFuzzyCompleterFuzzyWordCompleterc                   @  sl   e Zd ZdZdddddd	d
ddZddddddZddddZddddddZddddddZdS )r   a  
    Fuzzy completion.
    This wraps any other completer and turns it into a fuzzy completer.

    If the list of words is: ["leopard" , "gorilla", "dinosaur", "cat", "bee"]
    Then trying to complete "oar" would yield "leopard" and "dinosaur", but not
    the others, because they match the regular expression 'o.*a.*r'.
    Similar, in another application "djm" could expand to "django_migrations".

    The results are sorted by relevance, which is defined as the start position
    and the length of the match.

    Notice that this is not really a tool to work around spelling mistakes,
    like what would be possible with difflib. The purpose is rather to have a
    quicker or more intuitive way to filter the given completions, especially
    when many completions have a common prefix.

    Fuzzy algorithm is based on this post:
    https://blog.amjith.com/fuzzyfinder-in-10-lines-of-python

    :param completer: A :class:`~.Completer` instance.
    :param WORD: When True, use WORD characters.
    :param pattern: Regex pattern which selects the characters before the
        cursor that are considered for the fuzzy matching.
    :param enable_fuzzy: (bool or `Filter`) Enabled the fuzzy behavior. For
        easily turning fuzzyness on or off according to a certain condition.
    FNTr   boolz
str | Noner   None)	completerWORDpatternenable_fuzzyreturnc                 C  s<   |d ks| dst|| _|| _|| _|| _t|| _d S )N^)
startswithAssertionErrorr   r   r   r	   r   )selfr   r   r   r    r   M/tmp/pip-unpacked-wheel-9s95tbmv/prompt_toolkit/completion/fuzzy_completer.py__init__0   s    zFuzzyCompleter.__init__r   r   Iterable[Completion]documentcomplete_eventr   c                 C  s&   |   r| ||S | j||S d S N)r   _get_fuzzy_completionsr   get_completionsr   r#   r$   r   r   r   r'   ?   s    zFuzzyCompleter.get_completionsstrr   c                 C  s   | j r| j S | jrdS dS )Nz[^\s]+z^[a-zA-Z0-9_]*)r   r   )r   r   r   r   _get_patternG   s
    zFuzzyCompleter._get_patternc              	   c  sH  |j t|  d}t|jd |jt|  |jt| d}t| j	
||}g }|dkrndd |D }ndttj|}d| d}t|tj}|D ]H}	t||	j}
|
rt|
d	d
 d}|tt|d| |	 qddddd}t||d}|D ]:}t|jj|jjt| |jj| |||jjdV  qd S )N)r   )textcursor_position c                 S  s   g | ]}t d d |qS )r   )_FuzzyMatch).0complr   r   r   
<listcomp>e   s     z9FuzzyCompleter._get_fuzzy_completions.<locals>.<listcomp>z.*?z(?=(z))c                 S  s   |   t| dfS )Nr   )startlengroup)mr   r   r   <lambda>n       z7FuzzyCompleter._get_fuzzy_completions.<locals>.<lambda>)keyr   r/   ztuple[int, int])fuzzy_matchr   c                 S  s   | j | jfS )z8Sort by start position, then by the length of the match.)	start_posmatch_length)r:   r   r   r   sort_keys   s    z7FuzzyCompleter._get_fuzzy_completions.<locals>.sort_key)r,   start_positionZdisplay_metadisplaystyle)Zget_word_before_cursorrecompiler+   r   r,   r-   r4   listr   r'   joinmapescape
IGNORECASEfinditerminappendr/   r5   r3   sortedr   
completionr>   Z_display_meta_get_displayr@   )r   r#   r$   word_before_cursorZ	document2Zinner_completionsZfuzzy_matchespatregexr1   matchesbestr=   matchr   r   r   r&   N   sF    
z%FuzzyCompleter._get_fuzzy_completionsr/   r
   )r:   rN   r   c                   s   dd fdd}| S )z@
        Generate formatted text for the display label.
        r
   r*   c                    s    } | j j}| jdkr| j jS g }|d|d | j f t}|| j| j| j  D ]<}d}|r| |d  kr|d7 }|d= |||f qX|d|| j| j d  f |S )Nr   zclass:fuzzymatch.outsidezclass:fuzzymatch.insidez
.character)rL   r,   r<   r?   rJ   r;   rC   lower)r6   wordresult
charactersc	classnamer:   rN   r   r   get_display   s"    
z0FuzzyCompleter._get_display.<locals>.get_displayr   )r   r:   rN   r[   r   rZ   r   rM      s    !zFuzzyCompleter._get_display)FNT)	__name__
__module____qualname____doc__r    r'   r+   r&   rM   r   r   r   r   r      s      8c                   @  s8   e Zd ZdZddddddd	d
ZddddddZdS )r   aA  
    Fuzzy completion on a list of words.

    (This is basically a `WordCompleter` wrapped in a `FuzzyCompleter`.)

    :param words: List of words or callable that returns a list of words.
    :param meta_dict: Optional dict mapping words to their meta-information.
    :param WORD: When True, use WORD characters.
    NFz+Sequence[str] | Callable[[], Sequence[str]]zdict[str, str] | Noner   r   )words	meta_dictr   r   c                 C  sB   || _ |pi | _|| _t| j | j| jd| _t| j| jd| _d S )N)r`   r   ra   )r   )r`   ra   r   r   word_completerr   fuzzy_completer)r   r`   ra   r   r   r   r   r       s    
  zFuzzyWordCompleter.__init__r   r   r!   r"   c                 C  s   | j ||S r%   )rc   r'   r(   r   r   r   r'      s    z"FuzzyWordCompleter.get_completions)NF)r\   r]   r^   r_   r    r'   r   r   r   r   r      s
     c                   @  s&   e Zd ZU ded< ded< ded< dS )r/   intr<   r;   r   rL   N)r\   r]   r^   __annotations__r   r   r   r   r/      s   
r/   )
__future__r   rA   typingr   r   r   r   Zprompt_toolkit.documentr   Zprompt_toolkit.filtersr   r	   Zprompt_toolkit.formatted_textr
   r   baser   r   r   rb   r   __all__r   r   r/   r   r   r   r   <module>   s    !