<s> from Vintageous . ex . ex_error import ERR_NO_RANGE_ALLOWED <EOL> from Vintageous . ex . ex_error import VimError <EOL> from Vintageous . ex . parser . tokens import TokenDigits <EOL> from Vintageous . ex . parser . tokens import TokenDollar <EOL> from Vintageous . ex . parser . tokens import TokenDot <EOL> from Vintageous . ex . parser . tokens import TokenMark <EOL> from Vintageous . ex . parser . tokens import TokenOffset <EOL> from Vintageous . ex . parser . tokens import TokenOfSearch <EOL> from Vintageous . ex . parser . tokens import TokenPercent <EOL> from Vintageous . ex . parser . tokens import TokenSearchBackward <EOL> from Vintageous . ex . parser . tokens import TokenSearchForward <EOL> from Vintageous . vi . search import reverse_search_by_pt <EOL> from Vintageous . vi . utils import first_sel <EOL> from Vintageous . vi . utils import R <EOL> from Vintageous . vi . utils import row_at <EOL> class Node ( object ) : <EOL> pass <EOL> class RangeNode ( Node ) : <EOL> '''<STR_LIT>''' <EOL> def __init__ ( self , start = None , end = None , separator = None ) : <EOL> self . start = start or [ ] <EOL> self . end = end or [ ] <EOL> self . separator = separator <EOL> def __str__ ( self ) : <EOL> return '<STR_LIT>' . format ( <EOL> '<STR_LIT>' . join ( str ( x ) for x in self . start ) , <EOL> str ( self . separator ) if self . separator else '<STR_LIT>' , <EOL> '<STR_LIT>' . join ( str ( x ) for x in self . end ) , <EOL> ) <EOL> def __rpr__ ( self ) : <EOL> return ( '<STR_LIT>' <EOL> . format ( self . __class__ . __name__ , self . start , self . end , self . separator ) ) <EOL> def __eq__ ( self , other ) : <EOL> if not isinstance ( other , RangeNode ) : <EOL> return False <EOL> return ( self . start == other . start and <EOL> self . end == other . end and <EOL> self . separator == other . separator ) <EOL> @ property <EOL> def is_empty ( self ) : <EOL> '''<STR_LIT>''' <EOL> return not any ( ( self . start , self . end , self . separator ) ) <EOL> def resolve_notation ( self , view , token , current ) : <EOL> '''<STR_LIT>''' <EOL> if isinstance ( token , TokenDot ) : <EOL> pt = view . text_point ( current , <NUM_LIT:0> ) <EOL> return row_at ( view , pt ) <EOL> if isinstance ( token , TokenDigits ) : <EOL> return max ( int ( str ( token ) ) - <NUM_LIT:1> , - <NUM_LIT:1> ) <EOL> if isinstance ( token , TokenPercent ) : <EOL> return row_at ( view , view . size ( ) ) <EOL> if isinstance ( token , TokenDollar ) : <EOL> return row_at ( view , view . size ( ) ) <EOL> if isinstance ( token , TokenOffset ) : <EOL> return current + sum ( token . content ) <EOL> if isinstance ( token , TokenSearchForward ) : <EOL> start_pt = view . text_point ( current , <NUM_LIT:0> ) <EOL> match = view . find ( str ( token ) [ <NUM_LIT:1> : - <NUM_LIT:1> ] , start_pt ) <EOL> if not match : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> return row_at ( view , match . a ) <EOL> if isinstance ( token , TokenSearchBackward ) : <EOL> start_pt = view . text_point ( current , <NUM_LIT:0> ) <EOL> match = reverse_search_by_pt ( view , str ( token ) [ <NUM_LIT:1> : - <NUM_LIT:1> ] , <NUM_LIT:0> , start_pt ) <EOL> if not match : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> return row_at ( view , match . a ) <EOL> if isinstance ( token , TokenMark ) : <EOL> return self . resolve_mark ( view , token ) <EOL> raise NotImplementedError ( ) <EOL> def resolve_mark ( self , view , token ) : <EOL> if token . content == '<STR_LIT:<>' : <EOL> sel = list ( view . sel ( ) ) [ <NUM_LIT:0> ] <EOL> view . sel ( ) . clear ( ) <EOL> view . sel ( ) . add ( sel ) <EOL> if sel . a < sel . b : <EOL> return row_at ( view , sel . a ) <EOL> else : <EOL> return row_at ( view , sel . a - <NUM_LIT:1> ) <EOL> if token . content == '<STR_LIT:>>' : <EOL> sel = list ( view . sel ( ) ) [ <NUM_LIT:0> ] <EOL> view . sel ( ) . clear ( ) <EOL> view . sel ( ) . add ( sel ) <EOL> if sel . a < sel . b : <EOL> return row_at ( view , sel . b - <NUM_LIT:1> ) <EOL> else : <EOL> return row_at ( view , sel . b ) <EOL> raise NotImplementedError ( ) <EOL> def resolve_line_reference ( self , view , line_reference , current = <NUM_LIT:0> ) : <EOL> '''<STR_LIT>''' <EOL> last_token = None <EOL> current = row_at ( view , first_sel ( view ) . b ) <EOL> for token in line_reference : <EOL> if isinstance ( last_token , TokenOfSearch ) and isinstance ( token , TokenOfSearch ) : <EOL> if isinstance ( token , TokenSearchForward ) : <EOL> current += <NUM_LIT:1> <EOL> current = self . resolve_notation ( view , token , current ) <EOL> last_token = token <EOL> return current <EOL> def resolve ( self , view ) : <EOL> '''<STR_LIT>''' <EOL> start = self . resolve_line_reference ( view , self . start or [ TokenDot ( ) ] ) <EOL> if not self . separator : <EOL> if start == - <NUM_LIT:1> : <EOL> return R ( - <NUM_LIT:1> , - <NUM_LIT:1> ) <EOL> if len ( self . start ) == <NUM_LIT:1> and isinstance ( self . start [ <NUM_LIT:0> ] , TokenPercent ) : <EOL> return R ( <NUM_LIT:0> , view . size ( ) ) <EOL> return view . full_line ( view . text_point ( start , <NUM_LIT:0> ) ) <EOL> new_start = start if self . separator == '<STR_LIT:;>' else <NUM_LIT:0> <EOL> end = self . resolve_line_reference ( view , self . end or [ TokenDot ( ) ] , current = new_start ) <EOL> return view . full_line ( R ( view . text_point ( start , <NUM_LIT:0> ) , view . text_point ( end , <NUM_LIT:0> ) ) ) <EOL> class CommandLineNode ( Node ) : <EOL> def __init__ ( self , line_range , command ) : <EOL> self . line_range = line_range <EOL> self . command = command <EOL> def __str__ ( self ) : <EOL> return '<STR_LIT>' . format ( str ( self . line_range ) , str ( self . command ) ) <EOL> def validate ( self ) : <EOL> '''<STR_LIT>''' <EOL> if not ( self . command and self . line_range ) : <EOL> return <EOL> if not self . command . addressable and not self . line_range . is_empty : <EOL> raise VimError ( ERR_NO_RANGE_ALLOWED ) </s>
