<s> """<STR_LIT>""" <EOL> from __future__ import unicode_literals <EOL> from abc import ABCMeta , abstractmethod <EOL> from six import with_metaclass <EOL> from six . moves import range <EOL> from prompt_toolkit . token import Token <EOL> from prompt_toolkit . filters import to_cli_filter <EOL> from . utils import split_lines <EOL> import re <EOL> import six <EOL> __all__ = ( <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> ) <EOL> class Lexer ( with_metaclass ( ABCMeta , object ) ) : <EOL> """<STR_LIT>""" <EOL> @ abstractmethod <EOL> def lex_document ( self , cli , document ) : <EOL> """<STR_LIT>""" <EOL> class SimpleLexer ( Lexer ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , default_token = Token ) : <EOL> self . default_token = default_token <EOL> def lex_document ( self , cli , document ) : <EOL> lines = document . lines <EOL> def get_line ( lineno ) : <EOL> "<STR_LIT>" <EOL> try : <EOL> return [ ( self . default_token , lines [ lineno ] ) ] <EOL> except IndexError : <EOL> return [ ] <EOL> return get_line <EOL> class SyntaxSync ( with_metaclass ( ABCMeta , object ) ) : <EOL> """<STR_LIT>""" <EOL> @ abstractmethod <EOL> def get_sync_start_position ( self , document , lineno ) : <EOL> """<STR_LIT>""" <EOL> class SyncFromStart ( SyntaxSync ) : <EOL> """<STR_LIT>""" <EOL> def get_sync_start_position ( self , document , lineno ) : <EOL> return <NUM_LIT:0> , <NUM_LIT:0> <EOL> class RegexSync ( SyntaxSync ) : <EOL> """<STR_LIT>""" <EOL> MAX_BACKWARDS = <NUM_LIT> <EOL> FROM_START_IF_NO_SYNC_POS_FOUND = <NUM_LIT:100> <EOL> def __init__ ( self , pattern ) : <EOL> assert isinstance ( pattern , six . text_type ) <EOL> self . _compiled_pattern = re . compile ( pattern ) <EOL> def get_sync_start_position ( self , document , lineno ) : <EOL> "<STR_LIT>" <EOL> pattern = self . _compiled_pattern <EOL> lines = document . lines <EOL> for i in range ( lineno , max ( - <NUM_LIT:1> , lineno - self . MAX_BACKWARDS ) , - <NUM_LIT:1> ) : <EOL> match = pattern . match ( lines [ i ] ) <EOL> if match : <EOL> return i , match . start ( ) <EOL> if lineno < self . FROM_START_IF_NO_SYNC_POS_FOUND : <EOL> return <NUM_LIT:0> , <NUM_LIT:0> <EOL> else : <EOL> return lineno , <NUM_LIT:0> <EOL> @ classmethod <EOL> def from_pygments_lexer_cls ( cls , lexer_cls ) : <EOL> """<STR_LIT>""" <EOL> patterns = { <EOL> '<STR_LIT>' : r'<STR_LIT>' , <EOL> '<STR_LIT>' : r'<STR_LIT>' , <EOL> '<STR_LIT>' : r'<STR_LIT>' , <EOL> '<STR_LIT>' : r'<STR_LIT>' <EOL> } <EOL> p = patterns . get ( lexer_cls . name , '<STR_LIT>' ) <EOL> return cls ( p ) <EOL> class PygmentsLexer ( Lexer ) : <EOL> """<STR_LIT>""" <EOL> MIN_LINES_BACKWARDS = <NUM_LIT:50> <EOL> REUSE_GENERATOR_MAX_DISTANCE = <NUM_LIT:100> <EOL> def __init__ ( self , pygments_lexer_cls , sync_from_start = True , syntax_sync = None ) : <EOL> assert syntax_sync is None or isinstance ( syntax_sync , SyntaxSync ) <EOL> self . pygments_lexer_cls = pygments_lexer_cls <EOL> self . sync_from_start = to_cli_filter ( sync_from_start ) <EOL> self . pygments_lexer = pygments_lexer_cls ( <EOL> stripnl = False , <EOL> stripall = False , <EOL> ensurenl = False ) <EOL> self . syntax_sync = syntax_sync or RegexSync . from_pygments_lexer_cls ( pygments_lexer_cls ) <EOL> @ classmethod <EOL> def from_filename ( cls , filename , sync_from_start = True ) : <EOL> """<STR_LIT>""" <EOL> from pygments . util import ClassNotFound <EOL> from pygments . lexers import get_lexer_for_filename <EOL> try : <EOL> pygments_lexer = get_lexer_for_filename ( filename ) <EOL> except ClassNotFound : <EOL> return SimpleLexer ( ) <EOL> else : <EOL> return cls ( pygments_lexer . __class__ , sync_from_start = sync_from_start ) <EOL> def lex_document ( self , cli , document ) : <EOL> """<STR_LIT>""" <EOL> cache = { } <EOL> line_generators = { } <EOL> def get_syntax_sync ( ) : <EOL> "<STR_LIT>" <EOL> if self . sync_from_start ( cli ) : <EOL> return SyncFromStart ( ) <EOL> else : <EOL> return self . syntax_sync <EOL> def find_closest_generator ( i ) : <EOL> "<STR_LIT>" <EOL> for generator , lineno in line_generators . items ( ) : <EOL> if lineno < i and i - lineno < self . REUSE_GENERATOR_MAX_DISTANCE : <EOL> return generator <EOL> def create_line_generator ( start_lineno , column = <NUM_LIT:0> ) : <EOL> """<STR_LIT>""" <EOL> text = '<STR_LIT:\n>' . join ( document . lines [ start_lineno : ] ) [ column : ] <EOL> return enumerate ( split_lines ( self . pygments_lexer . get_tokens ( text ) ) , <EOL> start_lineno ) <EOL> def get_generator ( i ) : <EOL> """<STR_LIT>""" <EOL> generator = find_closest_generator ( i ) <EOL> if generator : <EOL> return generator <EOL> i = max ( <NUM_LIT:0> , i - self . MIN_LINES_BACKWARDS ) <EOL> if i == <NUM_LIT:0> : <EOL> row = <NUM_LIT:0> <EOL> column = <NUM_LIT:0> <EOL> else : <EOL> row , column = get_syntax_sync ( ) . get_sync_start_position ( document , i ) <EOL> generator = find_closest_generator ( i ) <EOL> if generator : <EOL> return generator <EOL> else : <EOL> generator = create_line_generator ( row , column ) <EOL> if column : <EOL> next ( generator ) <EOL> row += <NUM_LIT:1> <EOL> line_generators [ generator ] = row <EOL> return generator <EOL> def get_line ( i ) : <EOL> "<STR_LIT>" <EOL> try : <EOL> return cache [ i ] <EOL> except KeyError : <EOL> generator = get_generator ( i ) <EOL> for num , line in generator : <EOL> cache [ num ] = line <EOL> if num == i : <EOL> line_generators [ generator ] = i <EOL> if num + <NUM_LIT:1> in cache : <EOL> del cache [ num + <NUM_LIT:1> ] <EOL> return cache [ num ] <EOL> return [ ] <EOL> return get_line </s>
