@@ -109,25 +109,29 @@ impl VirtualFile {
109109 } ;
110110 }
111111
112- pub fn prev_line ( & mut self ) -> Option < & mut LoadedLine > {
113- if self . line_index == 0 {
114- assert ! ( self . loaded_chunks. start > 0 ) ;
112+ pub fn prev_line ( & mut self ) -> u16 {
113+ if self . line_index == 0 && self . loaded_chunks . start > 0 {
115114 // seek to previous chunk
116115 self . seek ( self . chunk_size * ( self . loaded_chunks . start - 1 ) ) ;
117116 }
118- self . line_index -= 1 ;
119- return self . chunk_lines . get_mut ( self . line_index ) ;
117+ // after possible seek, line_index may still be zero if there was nothing to load
118+ if self . line_index > 0 {
119+ self . line_index -= 1 ;
120+ return 1 ;
121+ }
122+ return 0 ;
120123 }
121124
122- pub fn next_line ( & mut self ) -> Option < & mut LoadedLine > {
123- let lines_count = self . chunk_lines . len ( ) ;
124- self . line_index += 1 ;
125- // "+1" because last line in the chunk may be incomplete
126- if self . line_index + 1 >= lines_count {
127- // seek to next chunk
125+ pub fn next_line ( & mut self ) -> u16 {
126+ if self . line_index + 2 >= self . chunk_lines . len ( ) {
127+ // fetch more lines, after increasing index it will be the last line which may be incomplete
128128 self . seek ( self . chunk_size * self . loaded_chunks . end ) ;
129129 }
130- return self . chunk_lines . get_mut ( self . line_index ) ;
130+ if self . line_index + 1 < self . chunk_lines . len ( ) {
131+ self . line_index += 1 ;
132+ return 1 ;
133+ }
134+ return 0 ;
131135 }
132136
133137 pub fn remove ( & mut self ) -> LoadedLine {
@@ -145,8 +149,12 @@ impl VirtualFile {
145149 return removed_line;
146150 }
147151
148- pub fn insert ( & mut self , new_line : LoadedLine ) {
149- self . chunk_lines . insert ( self . line_index , new_line) ;
152+ pub fn get_index ( & self ) -> usize {
153+ self . line_index
154+ }
155+
156+ pub fn insert_after ( & mut self , new_line : LoadedLine ) {
157+ self . chunk_lines . insert ( self . line_index + 1 , new_line) ;
150158 }
151159
152160 pub fn get ( & self ) -> & LoadedLine {
@@ -170,33 +178,26 @@ impl VirtualFile {
170178 count : usize ,
171179 ) -> impl Iterator < Item = & LoadedLine > {
172180 // TODO: This is inefficient and also clobbers the current line_index
173-
181+ let mut clobber : i32 = 0 ;
174182 if offset_from_line_index < 0 {
175183 // need to iterate lines backwards
176184 for _ in offset_from_line_index..0 {
177- self . prev_line ( ) ;
185+ clobber -= self . prev_line ( ) as i32 ;
178186 }
179187 } else {
180188 // need to iterate lines forwards
181189 for _ in 0 ..offset_from_line_index {
182- self . next_line ( ) ;
190+ clobber += self . next_line ( ) as i32 ;
183191 }
184192 }
185193 // line_index is now at the start of the range
194+ let start_index = self . line_index ;
186195 // materialize 'count' lines
187196 for _ in 0 ..count {
188- self . next_line ( ) ;
197+ clobber += self . next_line ( ) as i32 ;
189198 }
190-
191- // correct the line_index: go back to beginning of the range
192- for _ in 0 ..count {
193- self . prev_line ( ) ;
194- }
195- let start_index = self . line_index ;
196199 // ... and now go back to where line_index was before
197- for _ in 0 ..offset_from_line_index {
198- self . prev_line ( ) ;
199- }
200+ self . line_index = ( self . line_index as i32 - clobber) . try_into ( ) . unwrap ( ) ;
200201
201202 self . chunk_lines . iter ( ) . skip ( start_index)
202203 }
@@ -265,7 +266,7 @@ mod tests {
265266 let file = create_test_file ( "line1\n line2\n line3\n " ) ;
266267 let mut vf = VirtualFile :: new ( 10 , file) ;
267268 vf. seek ( 0 ) ;
268- vf. insert ( LoadedLine :: new ( "new_line" . to_string ( ) ) ) ;
269+ vf. insert_after ( LoadedLine :: new ( "new_line" . to_string ( ) ) ) ;
269270 assert_eq ! ( vf. get( ) . str ( ) , "new_line" ) ;
270271 }
271272
0 commit comments