a
    lc.                     @   s  d Z ddlZddlmZmZ ddlmZmZmZ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 d
dlmZmZ erddlmZ g dZG dd dedZG dd deZ G dd deZ!G dd deee"df e"f Z#e# Z$G dd deZ%dS )z
Adaptor classes for using Pygments lexers within prompt_toolkit.

This includes syntax synchronization code, so that we don't have to start
lexing at the beginning of a document, when displaying a very large text.
    N)ABCMetaabstractmethod)TYPE_CHECKINGCallableDict	GeneratorIterableOptionalTupleType)Document)FilterOrBool	to_filter)StyleAndTextTuples)split_linespygments_token_to_classname   )LexerSimpleLexer)r   )PygmentsLexer
SyntaxSyncSyncFromStart	RegexSyncc                   @   s.   e Zd ZdZeeeeeef dddZdS )r   a  
    Syntax synchroniser. This is a tool that finds a start position for the
    lexer. This is especially important when editing big documents; we don't
    want to start the highlighting by running the lexer from the beginning of
    the file. That is very slow when editing.
    documentlinenoreturnc                 C   s   dS )a/  
        Return the position from where we can start lexing as a (row, column)
        tuple.

        :param document: `Document` instance that contains all the lines.
        :param lineno: The line that we want to highlight. (We need to return
            this line, or an earlier position.)
        N selfr   r   r   r   Z/var/www/html/django/DPS/env/lib/python3.9/site-packages/prompt_toolkit/lexers/pygments.pyget_sync_start_position/   s    z"SyntaxSync.get_sync_start_positionN)	__name__
__module____qualname____doc__r   r   intr
   r"   r   r   r   r!   r   '   s
   
r   )	metaclassc                   @   s*   e Zd ZdZeeeeef dddZdS )r   zB
    Always start the syntax highlighting from the beginning.
    r   c                 C   s   dS )Nr   r   r   r   r   r   r!   r"   B   s    z%SyncFromStart.get_sync_start_positionN)r#   r$   r%   r&   r   r'   r
   r"   r   r   r   r!   r   =   s   
r   c                   @   sV   e Zd ZdZdZdZeddddZee	e
e	e	f dd	d
Zedd dddZdS )r   zQ
    Synchronize by starting at a line that matches the given regex pattern.
    i  d   N)patternr   c                 C   s   t || _d S )N)recompile_compiled_pattern)r    r+   r   r   r!   __init__U   s    zRegexSync.__init__r   c                 C   sf   | j }|j}t|td|| j dD ]&}||| }|r$|| f  S q$|| jk rZdS |dfS dS )zH
        Scan backwards, and find a possible position to start.
        r)   r   N)r.   linesrangemaxMAX_BACKWARDSmatchstartFROM_START_IF_NO_SYNC_POS_FOUND)r    r   r   r+   r1   ir5   r   r   r!   r"   X   s    
z!RegexSync.get_sync_start_positionPygmentsLexerCls)	lexer_clsr   c                 C   s$   ddddd}| |jd}| |S )zV
        Create a :class:`.RegexSync` instance for this Pygments lexer class.
        z^\s*(class|def)\s+z
<[/a-zA-Z]z\bfunction\b)PythonzPython 3HTML
JavaScript^)getname)clsr:   patternspr   r   r!   from_pygments_lexer_clsp   s    z!RegexSync.from_pygments_lexer_cls)r#   r$   r%   r&   r4   r7   strr/   r   r'   r
   r"   classmethodrD   r   r   r   r!   r   H   s   
r   c                   @   s(   e Zd ZdZeedf edddZdS )_TokenCachez
    Cache that converts Pygments tokens into `prompt_toolkit` style objects.

    ``Token.A.B.C`` will be converted into:
    ``class:pygments,pygments.A,pygments.A.B,pygments.A.B.C``
    .)keyr   c                 C   s   dt | }|| |< |S )Nzclass:r   )r    rH   resultr   r   r!   __missing__   s    z_TokenCache.__missing__N)r#   r$   r%   r&   r
   rE   rJ   r   r   r   r!   rG      s   rG   .c                   @   sh   e Zd ZdZdZdZded eee	 dddd	Z
edeed
dddZeeegef dddZdS )r   a  
    Lexer that calls a pygments lexer.

    Example::

        from pygments.lexers.html import HtmlLexer
        lexer = PygmentsLexer(HtmlLexer)

    Note: Don't forget to also load a Pygments compatible style. E.g.::

        from prompt_toolkit.styles.from_pygments import style_from_pygments_cls
        from pygments.styles import get_style_by_name
        style = style_from_pygments_cls(get_style_by_name('monokai'))

    :param pygments_lexer_cls: A `Lexer` from Pygments.
    :param sync_from_start: Start lexing at the start of the document. This
        will always give the best results, but it will be slow for bigger
        documents. (When the last part of the document is display, then the
        whole document will be lexed by Pygments on every key stroke.) It is
        recommended to disable this for inputs that are expected to be more
        than 1,000 lines.
    :param syntax_sync: `SyntaxSync` object.
    2   r*   TNr9   )pygments_lexer_clssync_from_startsyntax_syncr   c                 C   s4   || _ t|| _|dddd| _|p,t|| _d S )NF)stripnlstripallensurenl)rL   r   rM   pygments_lexerr   rD   rN   )r    rL   rM   rN   r   r   r!   r/      s    
zPygmentsLexer.__init__r   )filenamerM   r   c                 C   sP   ddl m} ddlm} z||}W n |y<   t  Y S 0 | |j|dS dS )z3
        Create a `Lexer` from a filename.
        r   )get_lexer_for_filename)ClassNotFound)rM   N)Zpygments.lexersrT   Zpygments.utilrU   r   	__class__)rA   rS   rM   rT   rU   rR   r   r   r!   from_filename   s    zPygmentsLexer.from_filename)r   r   c                    s   t tttf ddf }i  i tdfddtt| dfdddtt|d	fd
dt|dfddttd fdd}|S )z
        Create a lexer function that takes a line number and returns the list
        of (style_str, text) tuples as the Pygments lexer returns for that line.
        Nr   c                      s      rt S  jS dS )z8The Syntax synchronisation object that we currently use.N)rM   r   rN   r   )r    r   r!   get_syntax_sync   s    z3PygmentsLexer.lex_document.<locals>.get_syntax_sync)r8   r   c                    s4      D ]&\}}|| k r| | jk r|  S qdS )z@Return a generator close to line 'i', or None if none was found.N)itemsREUSE_GENERATOR_MAX_DISTANCE)r8   	generatorr   )line_generatorsr    r   r!   find_closest_generator   s    
z:PygmentsLexer.lex_document.<locals>.find_closest_generatorr   )start_linenocolumnr   c                 3   sB   t tttf  d fdd}ttt| E dH  dS )z
            Create a generator that yields the lexed lines.
            Each iteration it yields a (line_number, [(style_str, text), ...]) tuple.
            rX   c                  3   sF   d jd   d  } j| D ]\}}}t| |fV  q(d S )N
)joinr1   rR   get_tokens_unprocessed_token_cache)text_tv)r`   r   r    r_   r   r!   get_text_fragments  s    zUPygmentsLexer.lex_document.<locals>.create_line_generator.<locals>.get_text_fragmentsN)r   r
   rE   	enumerater   list)r_   r`   ri   )r   r    )r`   r_   r!   create_line_generator   s    $z9PygmentsLexer.lex_document.<locals>.create_line_generatorc                    s~   | }|r|S t d| j } | dkr2d}d}n | \}}| }|rT|S  ||}|rrt| |d7 }||< |S )z_
            Find an already started generator that is close, or create a new one.
            r   r   )r3   MIN_LINES_BACKWARDSr"   next)r8   r\   rowr`   )rl   r   r^   rY   r]   r    r   r!   get_generator  s"    
z1PygmentsLexer.lex_document.<locals>.get_generatorc                    sv   z
 |  W S  t yp   | }|D ]F\}}| |< || kr$| |< |d  v rZ |d =  |    Y S q$Y n0 g S )z*Return the tokens for a given line number.r   )KeyError)r8   r\   numline)cacherp   r]   r   r!   get_line7  s    

z,PygmentsLexer.lex_document.<locals>.get_line)r   )r   r
   r'   r   r   r	   )r    r   ZLineGeneratorru   r   )rt   rl   r   r^   rp   rY   r]   r    r!   lex_document   s    'zPygmentsLexer.lex_document)TN)T)r#   r$   r%   r&   rm   r[   r   r   r	   r   r/   rF   rE   rW   r   r   r'   r   rv   r   r   r   r!   r      s$      r   )&r&   r,   abcr   r   typingr   r   r   r   r   r	   r
   r   Zprompt_toolkit.documentr   Zprompt_toolkit.filtersr   r   Z"prompt_toolkit.formatted_text.baser   Z#prompt_toolkit.formatted_text.utilsr   Zprompt_toolkit.styles.pygmentsr   baser   r   Zpygments.lexerr9   __all__r   r   r   rE   rG   rd   r   r   r   r   r!   <module>   s$   (< 