<s> import itertools <EOL> class _Linewise ( object ) : <EOL> def __init__ ( self , buffer ) : <EOL> self . buffer = buffer <EOL> self . _lines = [ ] <EOL> def __eq__ ( self , other ) : <EOL> z = itertools . izip_longest ( self , other ) <EOL> return all ( line == other_line for line , other_line in z ) <EOL> def __ne__ ( self , other ) : <EOL> return not self == other <EOL> def __getitem__ ( self , i ) : <EOL> if not isinstance ( i , slice ) : <EOL> how_many = i - self . lines_read + <NUM_LIT:1> <EOL> elif i . stop is not None : <EOL> how_many = i . stop - self . lines_read <EOL> else : <EOL> how_many = None <EOL> self . buffer . _read_further ( how_many = how_many ) <EOL> return self . _lines [ i ] <EOL> def __setitem__ ( self , i , value ) : <EOL> if not isinstance ( i , slice ) : <EOL> how_many = i - self . lines_read + <NUM_LIT:1> <EOL> elif i . stop is not None : <EOL> how_many = i . stop - self . lines_read <EOL> else : <EOL> how_many = None <EOL> self . buffer . _read_further ( how_many = how_many ) <EOL> self . _lines [ i ] = value <EOL> def __iter__ ( self ) : <EOL> for line in self . _lines : <EOL> yield line <EOL> while True : <EOL> self . buffer . _read_further ( how_many = <NUM_LIT:1> ) <EOL> if not self . buffer . done_reading : <EOL> yield self [ - <NUM_LIT:1> ] <EOL> else : <EOL> return <EOL> def __len__ ( self ) : <EOL> self . buffer . _read_further ( ) <EOL> return self . lines_read <EOL> @ property <EOL> def lines_read ( self ) : <EOL> return len ( self . _lines ) <EOL> def append ( self , line ) : <EOL> self . _lines . append ( line ) <EOL> def extend ( self , lines ) : <EOL> self . _lines . extend ( lines ) <EOL> class _Charwise ( object ) : <EOL> def __init__ ( self , buffer ) : <EOL> self . buffer = buffer <EOL> self . lines = self . buffer . lines <EOL> def __eq__ ( self , other ) : <EOL> z = itertools . izip_longest ( self , other ) <EOL> return all ( c == other_c for c , other_c in z ) <EOL> def __ne__ ( self , other ) : <EOL> return not self == other <EOL> def __iter__ ( self ) : <EOL> for i , line in enumerate ( self . lines ) : <EOL> if i > <NUM_LIT:0> : <EOL> yield "<STR_LIT:\n>" <EOL> for c in line : <EOL> yield c <EOL> def __len__ ( self ) : <EOL> return sum ( len ( line ) + <NUM_LIT:1> for line in self . lines ) - <NUM_LIT:1> <EOL> def __str__ ( self ) : <EOL> return "<STR_LIT>" . join ( self ) <EOL> class Buffer ( object ) : <EOL> def __init__ ( self , iterable = ( u"<STR_LIT>" , ) ) : <EOL> self . _iter = iter ( iterable ) <EOL> self . lines = _Linewise ( self ) <EOL> self . chars = _Charwise ( self ) <EOL> self . done_reading = False <EOL> self . cursors = { } <EOL> def __getitem__ ( self , i ) : <EOL> return self . lines [ i ] <EOL> def __setitem__ ( self , i , value ) : <EOL> self . lines [ i ] = value <EOL> def __iter__ ( self ) : <EOL> return iter ( self . lines ) <EOL> def __len__ ( self ) : <EOL> return len ( self . lines ) <EOL> @ property <EOL> def lines_read ( self ) : <EOL> return self . lines . lines_read <EOL> def _read_further ( self , how_many = None ) : <EOL> if self . done_reading : <EOL> return <EOL> if how_many is not None : <EOL> for _ in xrange ( how_many ) : <EOL> try : <EOL> self . lines . append ( next ( self . _iter ) ) <EOL> except StopIteration : <EOL> self . done_reading = True <EOL> return <EOL> else : <EOL> self . lines . extend ( self . _iter ) <EOL> self . done_reading = True <EOL> def chars ( self , start = ( <NUM_LIT:0> , <NUM_LIT:0> ) , end = None ) : <EOL> if end is None : <EOL> end = ( len ( self ) - <NUM_LIT:1> , len ( self [ - <NUM_LIT:1> ] ) ) <EOL> first_row , first_col = start <EOL> last_row , last_col = end <EOL> if first_row == last_row : <EOL> return self [ first_row ] [ first_col : last_col ] <EOL> first = self [ first_row ] [ first_col : ] <EOL> middle = itertools . chain . from_iterable ( self [ first_row + <NUM_LIT:1> : last_row ] ) <EOL> last = self [ last_row ] [ : last_col ] <EOL> return itertools . chain ( first , middle , last ) <EOL> def delete ( self , start = ( <NUM_LIT:0> , <NUM_LIT:0> ) , end = None ) : <EOL> if end is None : <EOL> end = ( len ( self ) - <NUM_LIT:1> , len ( self [ - <NUM_LIT:1> ] ) ) <EOL> first_row , first_col = start <EOL> last_row , last_col = end <EOL> if first_row == last_row : <EOL> row = self [ first_row ] <EOL> self [ first_row ] = row [ : first_col ] + row [ last_col : ] <EOL> else : <EOL> self [ first_row ] = self [ first_row ] [ : first_col ] <EOL> self [ last_row ] = self [ last_row ] [ last_col : ] <EOL> self [ first_row + <NUM_LIT:1> : last_row ] = [ ] <EOL> def insert ( self , window , first_line , * lines ) : <EOL> row , column = cursor = self . cursors [ window ] <EOL> left , right = self [ row ] [ : column ] , self [ row ] [ column : ] <EOL> added = len ( lines ) <EOL> if lines : <EOL> last_line = lines [ - <NUM_LIT:1> ] <EOL> column = len ( last_line ) <EOL> else : <EOL> last_line = first_line <EOL> column += len ( first_line ) <EOL> self [ row ] = left + first_line <EOL> self [ row + <NUM_LIT:1> : row + <NUM_LIT:1> ] = lines <EOL> self [ row + added ] += right <EOL> for other in self . cursors . itervalues ( ) : <EOL> if other . row > row : <EOL> other . _row += added <EOL> cursor . coords = row + added , column <EOL> def write ( self , file ) : <EOL> file . writelines ( line + "<STR_LIT:\n>" for line in self ) <EOL> class Cursor ( object ) : <EOL> def __init__ ( self , window , coords = ( <NUM_LIT:0> , <NUM_LIT:0> ) ) : <EOL> self . _row , self . _column = coords <EOL> self . window = window <EOL> window . buffer . cursors [ window ] = self <EOL> def __eq__ ( self , other ) : <EOL> return self . coords == other <EOL> def __iter__ ( self ) : <EOL> yield self . row <EOL> yield self . column <EOL> def __ne__ ( self , other ) : <EOL> return self . coords != other <EOL> def __repr__ ( self ) : <EOL> return repr ( self . coords ) <EOL> def __reversed__ ( self ) : <EOL> yield self . column <EOL> yield self . row <EOL> @ property <EOL> def coords ( self ) : <EOL> return self . _row , self . _column <EOL> @ coords . setter <EOL> def coords ( self , coords ) : <EOL> self . _row , self . _column = coords <EOL> @ property <EOL> def column ( self ) : <EOL> return self . _column <EOL> @ column . setter <EOL> def column ( self , column ) : <EOL> self . _column = column <EOL> @ property <EOL> def row ( self ) : <EOL> return self . _row <EOL> @ row . setter <EOL> def row ( self , row ) : <EOL> self . _row = row <EOL> def trim ( self ) : <EOL> row , column , buffer = self . _row , self . _column , self . window . buffer <EOL> self . _row = row = max ( min ( len ( buffer ) - <NUM_LIT:1> , row ) , <NUM_LIT:0> ) <EOL> self . _column = max ( min ( len ( buffer [ row ] ) - <NUM_LIT:1> , column ) , <NUM_LIT:0> ) <EOL> class Window ( object ) : <EOL> def __init__ ( self , editor , buffer = None , cursor = ( <NUM_LIT:0> , <NUM_LIT:0> ) ) : <EOL> if buffer is None : <EOL> buffer = Buffer ( ) <EOL> self . editor = editor <EOL> self . buffer = buffer <EOL> self . cursor = Cursor ( self , coords = cursor ) <EOL> def insert ( self , * lines ) : <EOL> self . buffer . insert ( self , * lines ) <EOL> def chars ( self , start = None , * args , ** kwargs ) : <EOL> if start is None : <EOL> start = self . cursor . coords <EOL> return self . buffer . chars ( start = start , * args , ** kwargs ) <EOL> def delete ( self , start = None , * args , ** kwargs ) : <EOL> if start is None : <EOL> start = self . cursor . coords <EOL> return self . buffer . delete ( start = start , * args , ** kwargs ) <EOL> def backspace ( self ) : <EOL> self . cursor . column -= <NUM_LIT:1> <EOL> self . delete ( ) <EOL> class Tab ( object ) : <EOL> active_window = None <EOL> def __init__ ( self , editor , windows = None ) : <EOL> self . editor = editor <EOL> if windows is None : <EOL> window = self . active_window = Window ( editor ) <EOL> self . windows = [ [ window ] ] <EOL> else : <EOL> self . windows = windows <EOL> def __iter__ ( self ) : <EOL> return iter ( self . windows ) </s>
